Llevo varios días leyendo y con lapiz y papel intentando entender el confuso galimatías actual existente en la patente que os comente por encima en la entrada de hace unos días. 

Al final después de leerla y ordenr las ideas he llegado a la conclusión que citar la patente tal cual provocaría una situación de confusión enorme en los lectores de este blog que acabarían completamente locos por lo perverso y retorcido que es el lenguaje «Legalés» por lo que he pensado que lo mejor es explicar cual es el objetivo de la invención definiendo el problema y la solución que pretende adoptar.

El problema que tenemos actualmente en las GPUs de arquitectura GCN de AMD es que el limite esta en unos 64 CUs y la unica manera de solventar esto sería re-diseñar el planificador y el distribuidor de la GPU. Pensad que cada una de las CUs es un procesador en si mismo con una diferencia, solo tiene acceso a sus memoria locales y esta aislado del mundo por lo que recibe la lista de cosas a procesar en forma de olas por parte del Planificador y del Distribuidor que tienen un limite de funcionamiento. Toda GPU en general  sigue la siguiente organización:

GPUJobQueue1

El planificador es el procesador de comandos y otros procesadores en paralelo, se encargan de leer listas de comandos y generar las olas/wavefronts que son las listas de tareas a realizar. El Distribuidor es el que distribuye las tareas a las Compute Units que hay libres en cada momento por orden del planificador, un core puede ser una unidad shader programable o puede ser una unidad de función fija. Toda la planificación y distribución de las olas a las Compute Units son llevadas de manera transparente al programador por un complejo entramado de procesadores y memorias de una enorme complejidad que forman el planificador y el distribuidor. Obviamente la cantidad de elementos que el planificador puede organizar es limitada y se llega al punto en que la complejidad es tal que es necesario crear un nuevo planificador que expanda las capacidades.

 

¿Pero que podemos hacer para ampliar las capacidades de la GPU sin aumentar la complejidad del planificador? La patente nos da una solución para ello, pero antes de explicar dicha solución en lenguaje llano he de explicar lo que es una ola/wavefront. ¿Y que es una ola? Es un conjunto de lo que llamamos «kernels» no lo confundáis con el kernel de un sistema operativo, es una palabra homónima pero no del mismo significado. Un kernel es un pequeño programa, tan pequeño que es una instrucción+dato. Las olas cambian según la arquitectura pero se pueden definir como un caudal de kernels, en el caso de la arquitectura de AMD es de 64 elementos y en Nvidia de 32 elementos.

El Distribuidor distribuye unas n olas por ciclo de reloj por lo que si queremos alimentar todas las CUs al tiempo y tener la máxima ocupación posible y aumentar la cantidad de Compute Units por GPU tenemos que ir ampliando el planificador y el distribuidor en complejidad. ¿La solución que da la patente? Si en cada ola podemos empaquetar 64 elementos donde cada elemento es un kernel de una instrucción+dato por en cada uno de esos slots empaquetar varias instrucciones como mínimo 2 y esto es lo que propone la patente. Que empaquetemos en cada kernel de la ola una instrucción VLIW2. ¿Que es eso? Dejemos que Wikipedia nos lo explique

Del inglés Very Long Instruction Word. Esta arquitectura de CPU implementa una forma de paralelismo a nivel de instrucción. Es similar a las arquitecturas superescalares, ambas usan varias unidades funcionales (por ejemplo varias ALUs, varios multiplicadores, etc) para lograr ese paralelismo.

Los procesadores con arquitecturas VLIW se caracterizan, como su nombre indica, por tener juegos de instrucciones muy simples en cuanto a número de instrucciones diferentes, pero muy grandes en cuanto al tamaño de cada instrucción. Esto es así porque en cada instrucción se especifica el estado de todas y cada una de las unidades funcionales del sistema, con el objetivo de simplificar el diseño del hardware al dejar todo el trabajo de planificar el código en manos del programador/compilador, en oposición a un procesador superescalar, en el que es el hardware en tiempo de ejecución el que planifica las instrucciones.

La clave de todo es que esto nos permitiria en realidad empaquetar unas 2 instrucciones por Kernel en vez de una, pero la contrapartida es que necesitamos hacer una serie de cambios en las unidades SIMD de las Compute Units para poder hacer que pasen de procesar 1 instrucción por ciclo a unas 2 instrucciones por ciclo. ¿Que es una unidad SIMD?

En computación, SIMD (del inglésSingle Instruction, Multiple Data, en español: «una instrucción, múltiples datos») es una técnica empleada para conseguir paralelismo a nivel de datos.

345px-SIMD.svg

Los repertorios SIMD consisten en instrucciones que aplican una misma operación sobre un conjunto más o menos grande de datos. Es una organización en donde una única unidad de control común despacha las instrucciones a diferentes unidades de procesamiento. Todas éstas reciben la misma instrucción, pero operan sobre diferentes conjuntos de datos. Es decir, la misma instrucción es ejecutada de manera sincronizada por todas las unidades de procesamiento

En la arquitectura GCN tenemos unas 4 unidades SIMD en total, cada una de ellas tiene su banco de registros

kaveri-14b

En la FIG 1A de la patente relata la unidad SIMD en concreto y no toda la Compute Unit de una GPU con arquitectura GCN. El concepto (ALU Array) se refiera a la unidad SIMD16

FIG. 1A

No podríamos aplicar aqui el VLIW2 por el hecho de que tendríamos que tener dos ALUs operativas pero… La patente nos da una solución que es utilizando dos ALUs…

FIG1B

Que en la FIG. 4 se ve con mayor detalle.
FIG2Navi

Veamos…

El bloque Super-SIMD 300 incluye unidades de ejecución en vector 360. Cada una de ellas incluye dos colecciones de Core ALU 362a y 362b y una Side ALU, cada uno de ellas teniendo N numero de ALUs que son iguales a la longitud del SIMD. La Core ALU 362 a puede acoplada con la Side ALU 365 para formar la Full ALU 362. Full ALU es la segunda ALU 230 de la FIG. 1B. Core ALU 362b es la primera ALU 220 de la FIG 1G.

En una implementación, ambas Core ALU tienen N multiplicadores para ayudar a implementar ciertas operaciones de precisión simple como el  fused multiply-add (FMA). En una implementación, la side ALU 365 no tiene multiplicadores pero puede ayudar a implementar operaciones no-esencuiales como instrucciones de conversion. La Side ALU puede co-trabajar con cualquiera de las ALU 362a y 362b para finalizar operaciones complejas como instrucciones trascendentales.

Es decir, la instruccion VLIW2 al llegar directamente a la unidad SIMD de la Compute Unit se desglosaría simultaneamente en dos instrucciones que se ejecutarían al mismo tiempo, de dos maneras posibles.

  • Una instruccion compleja (Side ALU+Core ALU #0) y una instrucción simple (Core ALU#1)
  • Dos instrucciones simples (Core ALU#0 y Core ALU#1) en este caso la Side ALU queda completamente sin utilizar.

¿Que significa todo esto? Significa que podemos realizar el doble de operaciones por Compute Unit y alcanzar el doble teórico de FLOPS para empezar sin tener que duplicar la cantidad de Compute Units y tampoco tener que duplicar todo el planificador pero si la complejidad de cada Compute Unit al hacer más complejas las unidades SIMD y añadir internamente todo lo necesario para que las dos instrucciones funcionen en paralelo y sin problemas.

Si AMD no hace cambios en el planificador interno de cada Compute Unit (recordad que es un procesador dentro de un procesador) respecto a lo que tenemos en las unidades GCN hemos de tener en cuenta que cada Compute Unit tiene 4 unidades SIMD, por lo que pasaríamos a tener 4 unidades Super-SIMD y una configuración más bien como la del siguiente diagrama por Compute Unit.

FIG3Navi

Obviamente la memoria interna de cada Compute Unit tendría que ensancharse. Para empezar la LDS debido a que la Compute Unit ahora trabaja con Wavefronts el doble de complejos tendrá que aumentar su tamaño de los 64KB a los 128KB y luego los registros asignados a cada Super-SIMD pasarán de ser de 64KB a unos 128KB (32KB por banco VGRP). ¿Que nos queda? La Destination Operation Cache, pero explicar su funcionamiento sería demasiado complejo para el usuario de a pie y tendría que hacer una clase avanzada y tediosa de arquitectura de computadores y explicar de manera detallada como funciona una ALU en general así que…

meh

Y no, no es por desconocimiento sino porque no quiero desviar la entrada.

¿Es esto la Compute Unit de Navi o de la siguiente generación?

El titulo de la anterior entrada hacia referencia a unidad Post-GCN, en esta entrada tras reflexionar he decidido…

tableflip02

Y ahora os explicare el motivo, las patentes tardan de media unos 18 meses en hacerse públicas, de ahí que una patente de finales de 2016 se haya publicado justo ahora.

PatentSuperSIMDData.PNG

Sabemos que AMD tiene problemas a la hora de superar el limite de las 64 CUs, sabemos que tienen problemas con las veloidades de reloj por lo que esto es una buena solución para alcanzar rendimientos más altos sin tener que re-diseñar toda la arquitectura entera y si es la CU de Navi es posible que estemos ante la Compute Unit de Epsilon/PS5 y de la siguiente Xbox.

PS5Fake1

Con el cambio la tasa de FLOPS por ciclo de reloj y por CU se duplica por completo, utilizando los 14.2 TFLOPS con la nueva configuración he sacado una tabla de velocidades de reloj, cantidad de CUs y tasas de texturizado y de relleno, obviamente no son oficiales sino que es una tabla de especulación completamente mia, pero es para que os hagáis más o menos una idea.

Potencia CUs Mhz Gtexels/s Gpixels/s
14.2 TFLOPS 64 866,70 221,9 55,47
1,42E+013 60 924,48 221,9 59,17
1,42E+013 56 990,51 221,9 63,39
1,42E+013 52 1066,71 221,9 68,27
1,42E+013 48 1155,60 221,9 73,96
1,42E+013 44 1260,65 221,9 80,68
1,42E+013 40 1386,72 221,9 88,75
1,42E+013 36 1540,80 221,9 98,61

No voy a complicar la entrada más, sacad vuestras propias conclusiones de todo ello en los comentarios.