La controversia no para con Starfield, y es que
aunque NVIDIA haya conseguido aumentar el rendimiento un poco en
este juego con sus GPU RTX 30 y RTX 40, la
realidad es que la distancia entre las gráficas de los verdes y de
los rojos están muy próximas en este título. Se dijo que el driver
no estaba realmente bien optimizado y que NVIDIA no había dedicado
suficientes recursos a esto, pero nuevos datos apuntan más hacia
las bondades de la arquitectura de los rojos que a otra cosa.
¿Por qué Starfield rinde mejor en GPU AMD que en
NVIDIA cuando en el resto de juegos no es así?
Pues hay un triángulo de amor/odio para dar la explicación al
completo. El primero es la programación y codificación de Starfield
por parte de Bethesda. El segundo es una arquitectura de AMD que
exprime las bondades del juego, y por último y en tercer lugar, la
arquitectura de NVIDIA no trabaja tan bien como en otros
títulos.
Arquitectura de las RTX Ada y RX RDNA 3
RDNA 3 Navi 31 y Navi 32 (RX 7000)
Ada Lovelace (RTX 40)
Scalar Register File por SIMD/SM
10 KB
64 KB
Vector Register File por SIMD/SM
192 KB
64 KB
Vector/Texture Data L0 Cache por CU/SM
32 KB
64 KB
Scalar L1 Instruction Cache por WGP/SM
32 KB
128 KB
Scalar L1 Data Cache por WGP/SM
16 KB
128 KB
L1 Data Cache por SA/SM
256 KB
128 KB
L2 Data Cache por cada IMC de 32 Bits
512 KB
6.144 KB
La tabla superior que hemos hecho es la herramienta más
importante para este artículo, aunque no lo parezca. Todo el
argumento se va a basar en ella, o al menos, en gran parte, porque
ahí radican las peculiaridades de las arquitecturas.
Como seguro estáis al tanto, vamos a resumir los esquemas de los
dos chips más grandes para gaming de los que disponen ambas
compañías, y que corresponden con el AD102 y Navi 31.
En el caso de NVIDIA tenemos 12 GPC con 64 TPC,
que a su vez integran los 128 SM (AD102) para dar
la cifra de 16.384 Shaders en total.
AMD, por su parte, integra 6 Shaders Engines
con 12 Shaders Arrays, los cuales integran
48 WGP. Cada WGP contiene 2 CU,
lo que hace el recuento conocido de 96 CU en total
y con ello obtenemos los 6.144 Shaders
finales.
Este desgranamiento que es básico para comprender las
arquitecturas es clave para poder digerir el resumen de todo el
argumento que han lanzado los compañeros de Chips & chips
con sus pruebas en Starfield para las GPU de NVIDIA y AMD. En
concreto, se han probado 4 GPU:
RX 7900 XTX
RTX 4090
RTX 3090
TITAN RTX
Por motivos de comparación de arquitecturas y modelos, solo
hablaremos de las dos primeras, que son las últimas y más
interesantes, aunque las otras dos aparezcan lógicamente en los
datos.
Starfield en NVIDIA y AMD, un problema con las wave y
texturas
No es que el juego esté mal desarrollado per sé, simplemente
está más optimizado para la arquitectura AMD, y ahí se nota el
patrocinio. El análisis pormenorizado de una parte de un frame de
Starfield revela una gran cantidad de Dispatch
Calls que opera una cantidad gigantesca de elementos.
Sabiendo que la resolución escogida es 4K,
Starfield opera 6,8 millones de elementos por
frame, organizados en 213 mil wavefronts.
Para que nos entendamos y el concepto sea fácil de simplificar
en cálculos, los wavefronts son como subprocesos independientes. O
lo que es lo mismo, en un frame, como media, Starfield
envía 213.000 subprocesos a ejecutar por cada GPU, las
cuales, según su arquitectura, podrán trabajar con más o con menos,
lo que reducirá el tiempo para despechar las calls, y ahí un punto
importante.
Según AMD, la arquitectura RDNA 3 puede
trabajar con 64 wave, mientras que
NVIDIA trabaja con 32. Esto nos
da unos datos curiosos, puesto que la RX 7900 XTX
tendría que rastrear aproximadamente 3.072 y 6.144 procesos
en la RTX 4090.
Pero, las cuentas no cuadran. Ahí el siguiente punto, porque
tenemos que hablar de tasa de ocupación, clave para entender por
qué Starfield trabaja mejor en AMD.
El juego realiza unas llamadas a texturas muy bestias, muy
grandes, en bloques de gran tamaño y en poco tiempo, lo que
beneficia a la arquitectura de AMD porque tardará menos en
procesarlas para su posterior renderizado. Lo curioso es que la
llamada como tal es mejor en la tarjeta de los verdes, por poco sí,
frente a la de los rojos (1,15 ms vs 1,19).
Entonces, ¿qué está pasando?
La utilización de los Shaders y sus subprocesos
Volvemos un poco al apartado superior de la arquitectura, donde
en el caso de AMD y pormenorizando igual que en NVIDIA, cada uno
con sus nombres y unidades en concreto, Navi 31 como chip integra
en cada Shader Engines dos Shader Arrays. Cada
Shader Arrays integra dos WGP y cada uno de ellos
tiene cuatro SIMD.
Pues bien, cada SIMD tiene sus archivos de registro
independientes y sus dos CU internos. Lo importante a tratar aquí y
como ya vimos en los artículos de la arquitectura, es que cada
SIMD puede trabajar con 16
subprocesos gracias a un programador interno.
NVIDIA hace algo similar, porque cada SM está dividido en cuatro
partes llamadas SMSP (Streaming Multiprocessor
Sub-Partition), donde cada uno de estos SMSP tiene su propio
archivo de registro de 16.382 KB x 32 Bit, su L0, Warp
Scheduler y Dispatch. Todo ello alimenta a las unidades
FP32, INT32 y Tensor Core, y las cuatro partes comparten la L1 los
4 motores de texturas y los RT Cores de su SM.
Esta parrafada técnica es obligatoria para entender que cada
SMSP puede trabajar con 3 subprocesos, lo que nos
da 12 rastreos por ciclo. Esto se comparte con la
arquitectura Ampere, pero Turing solo puede trabajar con 8,
principalmente porque no tiene la nueva unidad FP32 por cada
SMSP.
¿Cómo trabajan los vectores y escalares en cada arquitectura
para su ocupación?
Comprendido lo anterior, ahora hay que entender que los rastreos
y subprocesos tienen que llenar las unidades para dotarlas de
trabajo, y aquí entran lógicamente las V-ALU (Float, INT
Matrix) y S-ALU para AMD, es decir, las ALU para calcular
vectores y las ALU para calcular escalares.
NVIDIA usa otras unidades en sus SM: FMA (Fused
Multiply-Add, pueden ser "Heavy o Lite"), SFU
(Special Function Units) y las ALU, pero
el valor más importante que ofrece Nsight Graphics es el de
SM Issue Active. Este parámetro está definido por
lo que se conoce como Theoretical Occupancy, donde la
propia NVIDIA lo define así dentro del área de la eficiencia en el
trabajo de cada tarea:
En tiempo de ejecución, el número de warps asignados a un
multiprocesador a la vez para cada ciclo se denomina Active
Warp. En el mejor de los casos, el promedio de Warp
activas en toda la ejecución del kernel es igual o muy cercano a la
ocupación teórica.
Sin embargo, si el programador no logra equilibrar la carga de
trabajo de manera uniforme entre los programadores de warp o
simplemente no queda trabajo restante para llenar la máquina, el
número real de warps activos puede ser significativamente menor que
la ocupación teórica. Las métricas discutidas se relacionan
entre sí por:
Límite de dispositivo >= Ocupación teórica >= Warps
activos
Por tanto, el SM Issue Active que se nombra es realmente el
Active Warp de NVIDIA en el gráfico, y como podemos ver, dado que
estamos trabajando con vectores en la mayoría de casos, se puede
apreciar que AMD utiliza mucho mejor las operaciones que NVIDIA,
donde curiosamente la RTX 3090 tiene una mayor tasa de ocupación
que la RTX 4090. En cambio, en escalares, NVIDIA tiene una ligera
ventaja que no compensa lo visto en vectores.
Tasa de ocupación
Después de tanto dato, volvamos otra vez arriba para recuperar
dos muy simples: RDNA 3 con Navi 31 puede trabajar con 16
subprocesos, NVIDIA con Ada Lovelace y AD102
puede hacerlo con 12. ¿Qué vemos en el gráfico que precede a este
párrafo? Pues los Warps por Waves que pueden usar cada modelo de
tarjeta.
Como se aprecia, la tasa de ocupación de la RX 7900 XTX
es mucho mejor que la de la RTX 4090 en Starfield, y por
lo tanto, esto tiene un impacto directo en la latencia, puesto que
si usas en gran cantidad los subprocesos que tienes disponibles
evitas el acceso a caché más de la cuenta, mejorando el
rendimiento, y en este caso la proporción de AMD es de más la mitad
(62,5%), mientras que NVIDIA solo consigue casi
llenar un tercio de dichos 12 subprocesos
(30,83%).
¿Qué está ocurriendo aquí? Bueno, de nuevo tenemos que volver a
la tabla superior, que vamos a poner una vez más para evitar el
scroll hasta arriba:
RDNA 3 Navi 31 y Navi 32 (RX 7000)
Ada Lovelace (RTX 40)
Scalar Register File por SIMD/SM
10 KB
64 KB
Vector Register File por SIMD/SM
192 KB
64 KB
Vector/Texture Data L0 Cache por CU/SM
32 KB
64 KB
Scalar L1 Instruction Cache por WGP/SM
32 KB
128 KB
Scalar L1 Data Cache por WGP/SM
16 KB
128 KB
L1 Data Cache por SA/SM
256 KB
128 KB
L2 Data Cache por cada IMC de 32 Bits
512 KB
6.144 KB
En este caso concreto de Starfield, NVIDIA no puede mejorar su
tasa de ocupación porque la cantidad de wavefronts en el juego es
tan alta que colapsan sus registros. Como hablamos
su momento con la RX 7600, dicha GPU obtenía una cantidad menor de
registros en sus SIMD, como bien muestra la famosa tabla inferior
que ya vimos en su día:
Los registros de los vectores por SIMD son calcados a RDNA 2, y
por eso llamamos a Navi 33 un RDNA 3 Lite, y
de ahí el que no escalase en rendimiento frente a sus predecesoras
como se suponía. Tenía un cuello de botella (literalmente, puesto
que RDNA 3 no lo tiene) que mermaba el
rendimiento.
Dado que cualquier GPU actual puede asignar de forma
dinámica la capacidad a ocupar entre archivos de registro de
distintos SIMD o SMSP según los subprocesos elegidos por
el Command Processor, o CP, este último puede hacer el mejor de los
trabajos posibles que si la cantidad de subprocesos activos no se
puede aprovechar (recordemos, 16 vs 12) porque los registros no
están accesibles, entonces la capacidad de ocupación
baja.
Esto es exactamente lo que le está pasando a las RTX 40 y RTX 30
en Starfield. Si vemos la tabla comparativa entre AMD y NVIDIA, los
rojos disponen de 192 KB por SIMD, mientras que
los verdes disponen de 64 KB por SM. Dada la
complejidad de las arquitecturas y el cómo están hechas podemos
resumir y simplificando mucho, que AMD integra menos unidades
mínimas, pero con mayores recursos disponibles en registros,
mientras que NVIDIA opta por lo contrario, muchas unidades mínimas
con registros más pequeños.
¿Qué hacer cuando tus registros son más pequeños?
Pues mueves la información a las cachés, y ahí viene el primer
problema. Mover información que tenía que ir en los registros y L0
a la L1 (en el caso de NVIDIA) supone una latencia que tiene que
ser paliada (ya que no queda más remedio). Por lo tanto, como la
arquitectura de AMD basa su ventaja en registros más grandes, la L0
puede dar un acierto mucho mayor que la de NVIDIA.
En concreto, y en el peor de los frames analizados, la L0 Vector
obtuvo algo más del 80% de acierto, mientras que
en NVIDIA, teniendo que salir a la L1, la tasa cayó al
63,30%, que no es muy alta, y por lo tanto, se
tuvo que pasar a la L2 para, ahora sí, aumentar el Hitrate al
97,10%.
Esto se ve perfectamente en el siguiente gráfico de Total Waves
por Warps para los Shaders. Hay que tener en cuenta que en el caso
de AMD, cuando las Wave32 fallan, hace uso de Wave64, lo que
consigue mantener más trabajo cuando el hitrate de las cachés
falla.
Aquí hay que recordar lo siguiente una vez más:
Las olas de Wave32 emiten cada
instrucción como máximo una vez.
Las olas Wave64 suelen emitir cada
instrucción dos veces: una vez para la mitad baja (elementos de
trabajo 31-0) y luego nuevamente para la mitad alta (elementos de
trabajo 63-32).
Conclusiones de Starfield en AMD y NVIDIA
Hay otro dato que todavía no hemos nombrado, aunque sí que lo
vimos en el artículo de la arquitectura RDNA
3 como tal, y no es más que el desacoplamiento de las
frecuencias entre Shader Clock y Front-End Clock.
El Shader Clock en RDNA 3 corre a 2,3
GHz, mientras que el Front-End Clock va a 2,5
GHz. Esto influye directamente en el rendimiento en
Starfield, porque el CP consigue repartir subprocesos a base de
Wavefronts de más rápido, lo que unido a todo lo dicho y un ancho
de banda en L2 más rápido posicionan a AMD a la altura o por encima
de NVIDIA en Starfield.
NVIDIA por su parte lo fía todo a una optimización de los
motores en wavefronts más pequeñas, y por eso su arquitectura
integra más SM y Shaders que la de AMD. Los archivos de registro
más pequeños pueden mantener menos trabajo y ocupación de
subprocesos en sus SMSP, pero al tener mayor número de unidades
mínimas totales (128 SM vs 96 CU) consiguen
impulsar el rendimiento al repartir el trabajo de forma
eficiente.
Además, en cuanto a área física y complejidad de diseño, tener
registros más pequeños y un programador más simple ayuda a crear un
chip con mayor número de unidades mínimas, "marca de la casa"
durante generaciones (Pascal, Maxwell, Turing, Ampere y Ada
Lovelace). No se necesitan muchos registros escalares o vectoriales
si el motor del juego no inunda al driver y programador con
Wavefronts, claro, pero si pasa, como es el caso, entonces la tasa
de acierto de la L1 se reducirá bastante por todo lo explicado,
mermando el rendimiento final.
No es que una arquitectura sea mala y otra buena, no es que haya
un problema aquí o allí, simplemente son distintas formas
de entender un mismo objetivo, y en este caso AMD consigue
imponerse o igualar a NVIDIA con menos Shaders por todos los
motivos mostrados para Starfield.
Por ello, Starfield es uno de esos juegos que le otorga
ventaja a AMD frente a NVIDIA, y por eso los rendimientos
están más parejos. Por desgracia, no se ha medido el acceso a la
VRAM, pero viendo el Hitrate de los verdes es más que probable que
habiendo habilitado rBAR y ganado rendimiento, dichos accesos sean
de mayor cuantía que en juegos más optimizados para la arquitectura
de NVIDIA. En cualquier caso, el misterio está, al menos,
parcialmente resuelto.