La API de bajo nivel de Xbox One según el SDK oficial (II)

Comentario original:

Me parece que o no te enteras de nada o no te quieres enterar, todo lo que ha confirmado el XDK y tu vas y te quedas con esto. Creo que a dia de hoy ya podemos decir que dx12 no se trata solo de ir a bajo nivel, sino de paralelizar las cosas que para eso la arquitectura de One está desdoblada en gran parte, incluido el doble contexto grafico, Sí, tambien lo pone en el XDK, que algunos solo hablan de lo que les interesa para adularse de que tenian razón, en fin sigue cuando hablas de la tecnologia que usaban las consolas del milenio pasado la clavas, sigue con ello.

Un poquito de logica por favor, no te quedes anclado en el pasado.

Como no soy mala persona y no soy un arrogante he decidido perder el tiempo leyendo el SDK buscando lo del “Doble Contexto Gráfico” y de lo que estáis hablando, así que defienda mi postura.

La documentación de Microsoft sobre Direct3D 11 explica muy bien lo que es el multihilo:

El multihilo esta diseñado para aumentar el rendimiento a través de realizar el trabajo utilizando uno o más hilos al mismo tiempo. En el pasado, esto ha nenido ha sido hecho generando un solo hilo principal para el renderizado y uno o más hilos para la preparación del trabajo como son la creación de objetos, la csrga, el procesamiento… Sin embergo, con la sincronización incluida en Direct3D 11, el objetivo detrás del multihilo es utilizar cada ciclo de la CPU y la GPU sin tener que hacer que un procesador espere al otro (particularmente haciendo que la GPU no tenga que esperar porque esto afecta directamente a la tasa de fotogramas). Haciendo esto, tu puedes generar la mayor cantiad de trabajo mientras mantienen la mejor tasa de fotogramas. El concepto de un solo fotograma para renderizar ya no es necesario desde que la API implemente la sincronización.

La idea detrás del multihilo en una GPU es que hay momentos en que la carga de trabajo es insuficiente para  que la GPU aproveche toda su potencia al 100% por lo que es una forma de poder aprovechar esos huecos en los que el procesador se encuentra parado. Una GPU no procesa un programa por si misma sino que lo que procesa es una lista (monohilo) o varias listas (multihilo) de comandos que le dicen que tienen que hacer por lo que su rendimiento dependerá de como estén organizadas las listas, hasta DX10 (y eso incluye de paso la GPU de Wii U que es de ese nivel) la GPU solo podía procesar una lista de comandos de tal manera que si un elemento de la lista tardaba mucho en procesarse los que venían detrás se veía afectados y esto es fatal para algo como el renderizado a tiempo real que depende del tiempo.

Pero para que la gente lo entienda mejor voy a hacer un simil para que de esta manera no se pierda en lo que explicare a continuación. Imaginad por un momento que las unidades shader de la GPU son las butacas de una sala de cine:

Ahora imaginad que todas y cada una de las personas que están haciendo cola para entrar al cine son las instrucciones de la lista de comandos que son enviadas por la CPU hacía la GPU.

colacine

Y la zona de taquillas es el procesador de comandos de la GPU que se encarga de gestionar los diferentes hilos.

Visto así nos podemos encontrar con tres situaciones distintas:

  • Hay una sola película en el cine y por tanto una sola taquilla.
  • Hay varias peliculas en el cine y una sola taquilla, se genera una cola enorme para conseguir las entradas y entrar en las diferentes salas.
  • Hay varias taquillas, gracias a ello las personas van entrando más rápidamente en la sala, esto además nos permite crear varias salas distintas cada una con una película diferente, por lo que podemos hacer que nuestro cine haga más películas/contextos.

Ahora bien… Dejemos por un momento lo que es Xbox One y vamos a ir a términos más generales. ¿Como se forman las colas de personas/listas de comandos?Hay un articulo de Brad Wardell en su blog, el cual os gusta tanto citar y es desarrollador, donde explica de forma muy clara como funciona la interacción CPU-GPU en el DirectX 11 estándar y como funcionará en el caso de DirectX 12, es importante leerlo para entrar en contexto y ver cual es el problema de DirectX 11 que lo explica muy bien.

Desde el comiendo del PC, hemos tenido el PC y la GPU (o al menos, “la tarjeta de video”).

Hasta DirectX 9, la CPU, siendo d eun solo núcleo en esos días, hablaría a la GPU a través del hilo “principal”.

DirectX 10 mejoro las cosas un poco permitiendo enviar varios trabajos a la GPU. Eso estaba bien, pero el pipeline A LA GPU (Esto es importante, no dice DE LA GPU, sino A LA GPU) aún estaba serializado. Así, que acababas con un núcleo de CPU hablando a un núcleo de la GPU.

El pasado otoño, Nvidia lanzo la GeForce 970 GTX. Tiene unos 5200 millones de transistores en su interior y ya soporta DirectX 12. Ahroa mismo,tiene miles de nucleos en su interior. Y con DirectX 11, yo puedo hablar exactamente con uno de ellos al mismo tiempo.

Mientras tanto, tu PC puede tener, 4, 8 o más núcleos de CPU en su interior. Y exactamente uno de ellos puede hablar al mismo tiempo a la GPU.

Parémonos un momento aquí. Me gustaría que lo pensaráis por un momento. Pensad por un momento lo limitante que es esto. Pensad en lo limitante que ha sido para los desarrolladores de videojuegos. ¿Desde cuando tu ordenador es multinúcleo?

En resumen:

DirectX 11: Tu CPU se comunica con la GPU de núcleo a núcleo cada vez. Es aún una gran mejora respecto a DirectX 9 donde un solo hilo estaba dedicado a hablar a la GPU pero aún estaba rascando la superficie.

DirectX 12: Cada núcleo puede hablar a la GPU al mismo tiempo, y dependiendo del controlador. Porá empezar a tomar control y hablarles a todos esos núcleos.

A lo que se refiere Warden con la comunicación CPU-GPU es que en Direct3D 11 el procesador de comandos de la GPU (Las taquillas del cine) solo procesan un cliente/hilo al mismo tiempo pese a que las GPUs son multihilo. ¿El motivo?. Para entender como funcionan las cosas en Direct3D 11 tenemos que tener en cuenta lo que son los “Contextos en Diferido”, cuya definición se puede encontrar también en el XDK de Xbox One y es la siguiente:

Traduccion:

Un contexto en diferido es un contexto de hilo seguro que puedes utilizar para grabar comandos gráficos en un hilo diferente al hilo principal de renderizado. Utilizando un contexto en diferido, tu puedes grabar comandos gráficos en una lista de comandos que es encapsulada por la interfaz ID3D11CommandList. Después que todos los items de la escena han sido grabados, entonces puedes enviarlos al hilo principal de renderizado para el rendering final. De esta manera puedes realizar tareas de renderizado de forma concurrente a través de múltiples hilos y potencialmente mejorar el rendimiento en escenarios con CPU multinúcleo. Tu puedes crear varios contextos en diferido.

Esto supone que aunque tengamos varios núcleos creando las listas de comandos para la GPU al final solo se hace una lista de comandos/cola de personas en el cine. Ese es el handicap que tiene Direct3D 11 en PC y que van a solucionar en Direct3D 12. Los contextos en diferido son aquellos contextos fuera del hilo de renderizado principal (al que llaman contexto inmediato) y se llaman en “diferido” por el hecho que se ejecutan en diferido, es decir con posteridad en el hilo principal de renderizado. Por lo que al final tenemos una sola cola con el cuello de botella que esto supone.

Ahora bien, en el caso de Xbox One… ¿que ocurre con el Direct3D 11 Mono de Xbox One? ¿Funciona igual que el Direct3D 11 estándar en este caso o tiene alguna mejora? Bueno, tiene una mejora bastante interesante:

Traduccion (de la parte que interesa):

… un contexto inmediato de computación asincrono puede ser utilizado para enviar cargas de trabajo compute shader a la GPU que funcionen en paralelo con las cargas de trabajo.

En D3D 11 Mono no tenemos un solo contexto inmediato, sino que tenemos dos contextos inmediatos, uno para computación y el otro para gráficos. Veamos lo que dice el XDK sobre el procesador de comandos, que es el que tiene que gestionar las dos listas:

Traducción:

La GPU de Xbox One soporta múltiples streams de comandos intercalados en hardware. Algunos de los streams contienen comandos de rendering, y otros son solo de computación. Ambos tipos de streams de comandos progresan a través de la GPU al mismo tiempo, compartiendo recursos de computación (se refiere a la potencia de la GPU en este caso, no al contexto de computación) y ancho de banda es posible desacoplar el trabajo de renderizado del trabajo de computación. Las tareas de computación pueden pasar por encima de las de renderizado, permitiendo traspasos de baja latencia entre la CPU y la GPU.

Ahora bien… ¿que ventajas supone el hecho de que la computación y los gráficos funcionen en paralelo? Hoy en día los juegos realizan una serie de efectos de post-procesado (por lo tanto se realizan con posteridad al pipeline gráfico) que son ejecutados a través de computación. En Direct3D 11 estandarsi tenemos x tiempo para renderizar la escena incluido el postprocesado entonces el tiempo es M+N=X donde M es el tiempo para renderizar la escena dejando muy poco tiempo a la computación N que se utiliza para el postprocesado u otras tareas de apoyo como es por ejemplo el procesamiento de las físicas del juego, la detección de colisiones… En Direct3D 11 Mono podemos hacer que N no ocurra después de M sino al mismo tiempo.

La GPU de Xbox One es una de arquitectura GCN 1.1, por lo que sabemos es la misma que la AMD Bonaire utilizada en la HD 7790 y la R7 260 En su diagrama se pueden ver un procesador de comandos y dos ACEs, los ACEs son los encargados de la lista de comandos para computación:

El procesador de comandos se encarga de evaluar si el contexto recibido es gráfico o de computación para ver que camino tomara, si es de computación entonces es enviado a los ACEs:

 

Pero claro, tenemos un procesador de comandos asociado a dos ACEs por lo que el sistema podría manejar perfectamente tres listas, una para gráficos y dos para computación. En la entrevista a los arquitectos del sistema Andrew Goosen dijo lo siguiente sobre el tema:

Andrew Goossen:  El numero de colas de computación asincrona que proveen los ACEs no afectan la cantidad de ancho de banda o el número efectivo de FLOPs o cualquier otra métrica de rendimiento de la GPU. En vez de ello, dictan el número de contextos simultáneos de hardware con los que el planificador de la GPU puede operar en cualquier momento dado. Puedes pensar en ellos como analógos a los hilos de software de la CPU, son hilos de ejecución lógicos que comparten el harware de la GPU. Tener más de ellos no mejora el rendimiento real del sistema.

En Xbox One tenemos por lo tanto dos ACEs, esto nos lo confirma uno de los arquitectos, pero en Direct3D 11 Mono tenemos el segundo ACE  de la GPU sin utilizar, por lo que no podemos utilizar el segundo contexto para computación. Es como si tuvieramos una taquilla con tres ventanillas y una de ellas estuviese cerrada. El mismo XDK lo confirma:

Traduccion (de la parte que nos interesa): 

… solo se puede crear un contexto de computación al mismo tiempo. Futuros XDKs expondran más de un contexto de computación al mismo tiempo.

La cosa se lía si tenemos en cuenta los siguientes diagramas sobre la arquitectura de la GPU, los cuales hacen aparecer un segundo procesador de comandos gráficos:

 

En toda la documentación no se habla en ningún momento del uso del segundo procesador de comandos gráficos ni se comenta en ningún momento del futuro le vayan a dar acceso a los desarrolladores a través del XDK. Estar esta, no lo puedo negar, pero es una enorme incognita y no podemos dar por hecho que los desarrolladores tendrán acceso al mismo en Xbox One. Para empezar en un mismo procesador de comandos gráficos se pueden ejecutar ya multiples contextos gráficos para renderizar la escena por lo que la existencia del segundo procesador de comandos es una incognita enorme sobretodo si tenemos en cuenta que las arquitecturas que son ya compatibles con DX12 en PC van a seguir utilizando uno por lo que no se puede asociar a DX12 lo del doble procesador de comandos. Lo único que se me ocurre es que cada procesador de comandos gráficos esta asociado a uno de los dos  sistemas operativo del sistema en los que corren las aplicaciones. Porque viendo lo que tenemos de documentación no se me ocurre otra cosa y no me atrevo a afirmar nada.

 

Anuncios