Skip to main content
AMD vs Nvidia

Async shaders y Async compute

Durante bastante tiempo se lleva discutiendo sobre la habilidad de usar capacidades de computación como el Async compute de un procesador gráfico para ayudar en el renderizado de un videojuego. Este asunto está ahora más que nunca en boca de todos porque es ahora cuando se empiezan a ver en cantidades importantes juegos que hacen uso de DirectX 12 o Vulkan, APIs modernas que pueden hacer uso de esa capacidad de computación y aplicarla a videojuegos.

El debate AMD vs Nvidia en este tema concreto viene dado por ciertas diferencias en la arquitectura de los procesadores gráficos de cada compañía que hacen que el tratamiento del Async compute sea diferente. Esto también hace que la lectura que se hace de los benchmarks de videojuegos DirectX 12 y Vulkan sea un poco diferente según la gráfica del fabricante que se esté analizando.

La diferencia en arquitecturas y el tratamiento del Async compute viene porque Nvidia no ha incluído en sus arquitecturas Async shaders. Tampoco en la reciente Pascal. Esto no quiere decir que el Async compute, la habilidad de separar las tareas de shading del renderizado, no esté soportado en las gráficas de Nvidia. Pascal y Maxwell lo soportan. En Maxwell cada GPC (Graphics Processing Cluster) puede trabajar en su tarea, que puede ser diferente de la tarea que puede tener asignada otro GPC. En Pascal hay más granularidad que en Maxwell y aquí cada SM (Streaming multiprocessor, los SM están contenidos dentro de un GPC) puede trabajar en una tarea distinta de los otros SM. Estas tareas pueden ser una mezcla de renderizado de gráficos y tareas de computación, que el scheduler ya se encargará de asignar dinámicamente esas tareas a la estructura correspondiente según la arquitectura que tengamos entre manos.

AMD a diferencia de Nvidia tiene Async shaders en los que puede descargar las tareas de computación de una forma totalmente independiente del pipeline de renderizado de gráficos.

En realidad, estas soluciones son dos caminos diferentes para intentar llegar a la misma solución. Se trata de separar gráficos de computación y enviarlos al procesador gráfico para intentar aumentar el uso de la GPU. Hay que entender que que el Async compute no es algo mágico, que simplemente por activarlo vaya a hacer que un videojuego aumente su rendimiento. Esto tiene que hacerse de una forma adecuada ya que de otra forma incluso podría ser contraproducente introduciendo cuellos de botella en sitios en los que de no usar esta técnica (me refiero a no usarla en el caso de que la uses mal) no estarían. El Async compute se enfoca más como un método para reducir la latencia en el procesado de cada fotograma, y como casi cualquier otra herramienta, nos podemos encontrar con problemas si se usa mal.

Async compute DX12En DirectX 11 y APIs de la época o anteriores, AMD no podía utilizar los ACE (Asyncronous Compute Engine) que había metido en su arquitectura GCN ya que esas APIs desconocían la existencia de ese nuevo hardware. Como consecuencia, la parte del procesador gráfico dedicado a la computación sufría y una parte de la GPU se veía infrautilizada. Con DirectX 12 y Vulkan ya pueden usarlos con lo que esas gráficas ahora pueden disfrutar de ganancias de rendimiento por permitirse el uso de partes del procesador gráfico que antes estaban prácticamente de adorno.

Maxwell y Pascal ya están utilizándose en su práctica totalidad. Estas arquitecturas no tienen un hardware como en la arquitectura GCN de AMD que no estaba siendo utilizado. Es por esto que forzar en arquitecturas como Maxwell el uso de Async compute no produce ganacias e incluso en ocasiones podría causar ineficiencias al sobrecargar el scheduler. Este scheduler ya está dinámicamente asignando tareas a los GPC/SM y forzando el Async compute te estás saltando en cierta medida el trabajo de ese scheduler, lo que puede llegar a causar pérdida de rendimiento. Pascal puede que no pierda rendimiento como Maxwell, pero es más que nada por la granularidad comentada antes a la hora de repartir tareas por SM en vez de por GPC.

Entonces, queda claro que Nvidia sí puede hacer Async compute pero no tienen Async shaders. Por lo tanto, en las gráficas de Nvidia no se pueden esperar ganancias de un 20-30% como se están viendo en algunos juegos con AMD porque las gráficas de Nvidia no tienen una parte del hardware infrautilizado. Los Async shaders son un añadido de la arquitectura GCN, pero no son requisito indispensable para alcanzar la compatibilidad con Async compute.

Benchmark doomAntes de que saliese el culebrón del Async compute, se hablaba de la mejora en las draw calls que iban a proporcionar DirectX 12 y Vulkan. Async compute es prácticamente irrelevante en este tema concreto. La parte importante de DirectX 12 y Vulkan para aumentar la capacidad de gestionar las draw calls y disminuir la sobrecarga a la CPU viene por la introducción de las listas de comandos multihilo. Nvidia lleva soportando listas de comando multihilo desde DirectX 11 y es por esto por lo que venía siendo habitual ver menos uso de CPU en DirectX 11 con el mismo juego en gráficas Nvidia que en las AMD. Con la introducción de las nuevas APIs, el terreno de juego en este aspecto se iguala.

Se puede pensar que el método de Nvidia de hacer Async compute es más ineficiente que el de AMD por hacerlo por software con su scheduler dinámico en vez de por hardware con ACEs. Pues depende. Nvidia diseñó el scheduler por software de Maxwell y Pascal con el fin de reducir al máximo la latencia en el procesado de fotogramas en todo lo posible distribuyendo dinámicamente la carga de trabajo entre los GPC/SM. Nvidia ha gastado muchos más recursos que AMD en este aspecto software de sus productos y el scheduler es rapidísimo y muy eficiente en su trabajo. La elección de AMD fue la de distribuir las cargas de trabajo por hardware en vez de por software, y en el caso de que todas las partes de la GPU puedan ser utilizadas, es muy bueno en ello. El asunto aquí es ese “en el caso de que…”. No siempre se cumple el argumento de hardware es mejor que software ante cualquier solución, y al menos en este caso, ambas soluciones tienen sus peculiaridades que igual se ven mejor con un ejemplo.

Cojamos la AMD 390 y la Nvidia 970. La 390 tiene 5,1 TFLOPS mientras que la 970 ronda los 4 TFLOPS. Nos encontramos con una gráfica que sobre el papel tiene bastante más capacidad de proceso que la otra y sin embargo en la época DirectX 11 hemos visto cómo ambas gráficas rivalizaban en rendimiento. El scheduler por software de Nvidia posibilitaba usar toda la capacidad de la 970 mientras que al no conocer DirectX 11 los ACEs de la AMD 390 los ACEs no podían repartir tareas de una forma adecuada y al no ser una solución software, no se podía enviar una actualización o similar para poder usar esos ACEs en DirectX 11.

Pero llega DirectX 12 y las cosas comienzan a cambiar. La AMD 390 no solo está superando de forma sostenida a la 970 sino que comienza a enfrentarse a la 980. ¿Por qué? Pues porque con DirectX 12 y Vulkan por fin los ACEs pueden repartir tareas por todo el procesador gráfico, haciendo que en este caso AMD también pueda empezar a tener una utilización casi total de sus procesadores gráficos en los videojuegos. La potencia bruta de la AMD 390 está muy pareja con la de la 980 y eso es lo que estamos viendo ahora en la práctica.

Por resumir un poco, Async compute solo va a dar grandes ganancias en el caso de que se hable de un hardware que estaba siendo infrautilizado con anterioridad, y esto es exactamente lo que está pasando con AMD.

 

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *