Sistema y Memoria

Tenemos dos elementos principales que podemos encontrar en la placa base de la consola,  el primero es una memoria DDR3 a 800Mhz con un bus de 64 bit, DDR3-1600, que es la llama memoria externa o MEM2.

WiiUMotherboard

El segundo es el MCM, que incluye el resto del sistema.

MCM

El MCM esta montado sobre un sustrato/interposer que engloba lo que en un SoC sería el uncore o los canales de comunicacion entre los procesadores y de estos con la memoria, los dos chips que se ven son:

  • Espresso: CPU
  • Latte: GX GPU,GX2 GPU, Controladores de E/S, eDRAMs, DSP de sonido

Volviendo a la RAM de los 2GB de memoria el sistema pero no la utiliza toda y se reserva 1GB solamente.

wiiumemorymap

Este es dificil de explicar pero digamos que al contrario que Xbox One y PS4 donde hay un bus Onion que crea la posibilidad a la GPU de conocer el estado de la memoria de la GPU, aquí esto no ocurre en ningún momento. Es decir, es como si dentro del barrio de casas la CPU tuviese la exclusiva de llevar mensajes a unas casas y la GPU tuviese la exclusiva para otras. El barrio obviamente es la MEM2, porque la MEM1/eDRAM es de uso exclusivo de la GPU y la CPU no tiene acceso a la misma en ningún momento, por lo que el acceso a la memoria no es coherente entre CPU y GPU ya que ambas utilizan direccionamientos distintos de memoria, La GPU mide de la dirección FFFFFFFF a la 00000000, mientras que la CPU hace el camino inverso. Pero no es que hayan unos 4GB de memoria, solo hay 1GB, solo que el direccionamiento en ambos casos es de 32 bits y  la GPU mapea a partir del FFFFFFFF mientras que la CPU mapea la misma memoria a partir del 00000000. Dicho de otra manera, el mismo espacio de memoria es mapeado de manera inversa en la CPU respecto a la GPU, pero hemos de tener en cuenta que hay espacios que ve la CPU que la GPU no ve y viceversa.

La GPU reserva para si misma:

  • 32MB del direccionamiento que corresponden a la MEM1.
  • 512MB del direccionamiento que corresponden a la MEM2.

La CPU tiene acceso al resto de la memoria MEM2, pero entre CPU y GPU en principio se reservan solo el primer GB. ¿Y que pasa con la memoria de 1GB a 2GB? Simplemente Wii U no la usa, se comento que era para las aplicaciones en segundo plano del sistema operativo, pero eso es un mito infundado de inicios de la consola cuando se pensaba que iba a utililizar un SO tan complejo como el de un smartphone y en realidad hace uso de un SO bastante complejo al que Nintendo por motivaciones propias le dio un uso más de acorde con la consola, las aplicaciones en segundo plano pueden absorber hasta 224MB de la memoria asignada, en realidad de 1024MB/1GB los juegos se llevan unos 768MB en una configuracíón de 256+512.

CPU Espresso

Con tal de facilitar la compatibilidad hacía atrás por un lado y permitir que la consola pudiese tener el factor forma que tiene en Nintendo optaron por una versión multinúcleo del PowerPC 750 utilizado en Gamecube y Wii, el cual en el MCM es el chip más pequeño de ambos. Con unos 25mm^2 aproximados de tamaño el chip es sumamente pequeño y esta considerado el cuello de botella por autonomasía del hardware de Wii U.

EspressoDie.jpg

Tenemos unos tres núcleos simétricos, cada uno núcleo es el mismo PowerPC 750 modificado para la Gamecube/Wii quec omo recordáreis sustituía su unidad FPU con capacidad para realizar operaciones de 64 bits en coma flotante por una capaz de hacer paired-singles, esto no era otra cosa que la capacidad de coger una ALU de 64 y hacer que fuese capaz de ejecutar la misma instruccion en dos valores de 32 bits y por tanto duplicar la capacidad de instrucciones en coma flotante a realizar, además que IBM añadió una serie de instrucciones exclusivas adicionales que servian para cumplimentar a la GX GPU del Flipper, esto en el caso de la Wii U no tiene utilidad alguna, la eleccion de este núcleo corresponde unica y llanamente a la compatibilidad hacía atrás de la consola.

750Gekko

El problema es que eso ya en Gamecube fue un cuello de botella en comparación con otras consolas, la capacidad de animar vertices de Gamecube era limitada, en Wii mejoro un poco por la subida de un 50% de la velocidad de reloj. En Wii U tenemos unos 3 núcleos y la velocidad ha mejorado levemente, pero dado el corto pipeline de dicha CPU la velocidad alcanzada solo llega a los 1.2 Ghz, por lo que la capacidad en coma flotante es muy, pero que muy pobre en ese aspecto. Dado que PS3 y 360 tiene bestias en coma flotante suelen utilizar la CPU para animar la escena mientras que dejan libre a la GPU para renderizar, en Wii U se tiene que tirar de GPU para liberar a la CPU de la carga de la animación. ¿El motivo? Puede realizar la mitad de las operaciones de reloj y para colmo solo alcanza los 1.2 Ghz de velocidad en vez de los 3.2 Ghz. ¿Y que hay de la potencia en enteros? Es un poco más rapida por ciclo de reloj por el hecho de ejecutar fuera de orden pero esa ventaja la pierde directamente por la baja velocidad de reloj, la potencia en enteros es importante en juegos con muchas instancias simultaneas como por ejemplo los juegos de mundo abierto donde hay varios personajes interactuando en pantalla, no es un problema que otras consolas no tengan pero Wii U se encuentra directamente con el problema de frente.

watch_dogs-wii-u-002

¿El gran cambio? El hecho que los tres núcleos, por temas de coherencia con la memoria, compartan la misma Cache L2, unos 3MB que se reparten de manera desigual:

  • Core 0: 512KB
  • Core 1: 2MB
  • Core 2: 512KB

Lo cual es sumamente extraño y no se el motivo de ello sinceramente. Lo que si que sabemos es que la cache L2 no es memoria SRAM sino DRAM, esto significa que la cantidad de transistores dedicados a la memoria es menor y con ello el tamaño del chip lo han podido reducir, pero 3MB es un overkill y uno esperaria una CPU más compleja, aunque con unos 25mm^2 de espacio poco se puede hacer.

Aunque la gran pregunta que todo el mundo se hizo cuando apareció la consola fue… ¿Por qué no colocar un PowerPC 970 modificado que podría mantener la compatibilidad hacía atrás? IBM podría haber modificado la FPU de esta para dar soporte a los Paired Singles y puede alcanzar velocidades de reloj mucho mayores que el 750 por tener un pipeline más largo, aparte de poder operar con más instrucciones de manera simultanea al tener el doble de unidades. No sabemos el motivo de la elección de Nintendo pero la influencia podría haber sido el hecho que Apple en su día tuvo problemas para montar un PowerBook (el nombre de los MacBook) en el el 2004-2005. Lo que fue uno de los motivos del paso a x86 de los Macintosh.

Pero Nintendo no es Apple o… ¿Hay alguna relacion? Digamos que el factor forma de la consola es el motivo de ello ya que limita las condiciones en las que el MCM puede operar.

slide010

La eleccion de la CPU por parte de Nintendo puede deberse al deseo de Nintendo de mantener los procesos de desarrollo de juegos de la era GameCube/Wii… ¿Las consecuencias? Una CPU muy poco potente que lastra a la GPU de mala manera provocando que el tiempo de renderizado en los casos donde hay mucha carga de CPU en la escena haga que la tasa de fotogramas sea baja o en su defecto los desarrolladores tengan que recortar efectos respecto a PS3 y Xbox 360 por el hecho de que un cuello de botella para la GPU.

SoC/LSI Latte

El Latte, fabricado por Renesas en su día es el componente más importante de Wii U, lo engloba todo excepto lo anteriormente descrito.

wiiugpudie

De cara  a los gráficos de Wii U lo que nos interesan son dos cosas, la eDRAM y la GX GPU2, la eDRAM a la que la GPU de Wii U tiene acceso es el espacio de eDRAM más grande, la otra es para la compatibilidad hacia atrás con la GX GPU (Wii/GCN), esta tiene unos 32MB de densidad y puede ser utilizada como memoria por cualquier tipo de dato de la GPU y no solo búfers de imagen, siempre y cuando quepan en la misma.

GX2 GPU

La GX2 GPU es una GPU DX10/OpenGL 3, se trata de una versión recortada de la familia R700 a 40nm, cuyo único representante en ese nodo de fabricacion en PC es el RV740 con 640 Stream Processors y una RAM de 51.2 GB/s, Wii U tiene una RAM de 12.8 GB/s (MEM2) y las especificaciones de la GPU son 1/4 de la misma.

WiiuGPUSpecs

La velocidad de reloj es de unos 550Mhz, aquí podemos ver un diagrama general.

GPU7BlockDiagram

Tenemos dos unidades SIMD de 16 componentes cada una conectada cada una a una unidad de texturas, si nos acercamos a las unidades TEX0 y TEX1 veremos que engloban cada una de ellas 4 unidades de texturas.

TUR700

Por lo que la tasa de texturizado es de (4400 millones de texeles, por debajo de los 8000 Texeles de Xbox 360 y los 12000 de PS3), en cuanto a las unidades SIMD, se trata de una unidad del tipo VLIW5.

GPU7SIMDDiagram

Por lo que tenemos un total de 80 ALUs por SIMD, haciendo el total de 160 ALUs. Pero es aquí donde entra la trampa, los Wavefronts suelen en las GPUs de AMD son de de 64 procesos cada uno que se subdividen en 4 grupos de 16 procesos cada uno en los que cada proceso se calcula en un ciclo. ¿Entonces? Digamos que la ALU_T es la ALU escalar de cuando una instrucción escalar (afecta a un operando en vez de varios) es ejecutada por la GPU por lo que las 5 ALUs jamás están activas al mismo tiempo y la capacidad en coma flotante de cara al Pixel/Fragment Shader es de 140.8 GFLOPS realmente, por debajo de los 192 GFLOPS de PS3 y podríamos concluir que en ese aspecto es la menos potente de las tres consolas de la generación HD.

La GX GPU2 puede leer las texturas de dos memorias distintas, tanto de la MEM1 como de la MEM2, cuando lo hace de la MEM1 normamente lo hace en el caso de efectos de post-procesado o para leer los Render Targets para el renderizado en diferido. Los desarrolladores pueden escoger donde almacenar los datos de textura de la escena en cada momento pero han de tener en cuenta que la MEM1 almacena también los búfers de imagen.

Los RB0 y RB1 son los clásicos Render Backend de AMD/ATI donde se encuentran los ROPS.

rop

Tenemos unos 4 ROPS en total por RBE y por lo tanto la configuración del sistema es de 8 ROPS. Su composicion es parecida a los de Xbox 360 pero es diferente, mientras los ROPS de 360 operaban sobre la eDRAM estos los hace en su cache interna y es un mecanismo que hasta el AMD Vega se ha mantenido intacto en el caso de AMD. Dado que estamos ante una GPU en origen DX10/OGL3 tiene que estar preparada para trabajar con hasta 8 muestras por lo que soporta MSAAx8 en el Inmediate Rendering y es capaz de trabajar con hasta 8 muestras/Render Targets en el Deferred, no obstante no se recomienda utilizar jamás la MEM2 por la falta de ancho de banda de esta para escribir el búfer de imagen por lo que se utiliza la eDRAM/MEM1 para ello.

Dada la densidad de 32MB de la eDRAM/MEM1 esta almacena también en el interior el búfer frontal en modo RGB, por lo que estariamos hablando de una memoria ideal para 6 muestras, Z+Stencil y Frontbuffer. La ventaja de ello es que al contario de Xbox 360 no tiene que recuperar los búfers resultantes de la memoria principal sino que este se almacena en los 32MB de RAM disponibles.

Aunque es una GPU del tipo DX10/OGL3 se recomienda utilizarla en un modo al estilo DX9/OGL2, la API propietaria (GX2) tiene un perfil para ello donde se elimina el uso del teselador y los Geometry Shaders y la cantidad de de Render Targets para de 8 a 4, en este modo se recomienda utilizar la eDRAM no utilizada para cargar las texturas de la escena en la MEM1 utilizando el DMAE.

El DMAE

El DMAE es una unidad que permite copiar datos de la MEM1 a la MEM2 sin que la GPU tenga que gastar ciclos de reloj del renderizado para ello.

Captura de pantalla 2016-04-29 a las 16.25.15

La función principal del DMA es la copia de datos dentro de las memorias.

DMAEWiiU

¿A que viene su importancia? Pese a que al contrario de GCN y Wii ahora tenemos una GPU con un sistema de caches que permite prescindir de la necesidad de memoria embebida para el filtraje además de permitir la ejecución de Pixel/Fragment Shaders, por que el espacio dedicado a las texturas en la memoria embebida ha desaparecido, pero las texturas se pueden leer directamente tanto de la MEM1 como de la MEM2, pero el ideal es hacerlo de la MEM1 ya que da mayor rendimiento. ¿Como se hace? Necesitamos ir volcando los datos de textura de la escena en cada momento desde la MEM2, hacerlo desde la CPU es un engorro por eso hace falta el DMAE, el cual es lo mismo que los Move Engines/DME de Xbox One en el fondo.

Si utilizamos unos 4 Render Targets+Z+Front Buffer de una resolución de 1280×720 pixeles, entonces nos encontramos con que para texturas en la MEM1 tenemos:

1280*720*4 bytes*(4 muestras+Z)= 18MB aprox.

1280*720*3 bytes= 2.7 MB aprox

Dado que la consola soporta compresión BC/S3TC (1 byte por pixel) entonces podemos almacenar todas las texturas del fotograma en solo 2MB solamente incluyendo los MIP Maps, aunque hemos de tener en cuenta que lo habitual es hacer uso de un atlas para almacenar las texturas de la misma y podemos utilizar un atlas de 4096*2048 y utilizar unos 8MB en ese caso para almacenar las texturas.

Compute Shaders en la GX2 GPU y el tema de la animación de la escena.

La GX2 GPU al ser una GPU DX10/OGL3 no puede realizar contexto gráfico y de computación de manera paralela y asincrona, tiene que elegir entre ambos contextos por lo que a la hora del renderizado de escenas en 3D a tiempo real no se hace uso de los Compute Shaders y tiene una visión completamente reducida de los mismos. Pero sobretodo se ha de tener en cuenta que durante los tiempos muertos del renderizado el acceso a la GPU para computación en modo que la GPU trabaje como co-procesador de la CPU es imposible.

captura-de-pantalla-2016-04-29-a-las-14-11-25

¿Entonces? Los Compute Shaders pueden ser invocados en el tiempo previo al renderizado donde la GPU no dibuja nada, es decir, cuando esta esta creando las listas de pantalla la GPU puede hacer algo. ¿Y que es lo que hace? Recorte de primitivas no visibles, es lo mismo que se hace con los SPE en el CBEA, la idea es reducir el tiempo del Vertex Shader.

¿Otra aplicación? Los efectos de post-procesado que están por tanto fuera del pipeline gráfico, pero el mismo principio se puede aplicar para el renderizado de los juegos en 2D, la gran mayoría hoy en dia se renderizan utilizando el pipeline de computación y no el gráfico. Esto es porque en una escena 2D solo tenemos que dibujar los pixeles en pantalla, no existe el pipeline geometrico aunque no podemos confundir un juego de jugabilidad 2D con un juego renderizado en 2D.

¿Pero y que hay de la animación? Antes he dicho que la animación se hace desde la GPU en Wii U o se recomienda hacerla, lo cual es cierto, pero no es por Compute Shaders sino a través de los Vertex Shaders, la ventaja que tienen Xbox 360 y Wii U con esa enorme cantidad de shaders es que en la etapa de la geometría apenás se usan y se pueden direccionar para otras cosas. ¿Como lo hace? Pasando las matrices de transformación como texturas durante el Vertex Shader y/o el Geometry Shader para animar la escena utilizando los shaders, de esta manera eliminamos la carga de la animacion sobre la CPU… ¿La contrapartida? Reducimos la geométria máxima que se puede procesar, pero en todo caso hemos de tener en cuenta que el rasterizador (el cual solo puede generar un triangulo por ciclo) puede enviarle menos fragmentos a las unidades de texturas que los que durante la etapa geometrica puede procesar utilizando todos los shaders, por lo que utilizar los VS para la animación no es realmente algo descabellado.

Y con esto terminamos la serie de una vez por todas ya que con esto hemos cubierto ya todos los sistemas.

PD: Si queréis hacer un set de preguntas sobre esta serie de entradas en los comentarios, no solo de esta sino también de todas las demás.