Para entender como funciona la unidad Super-SIMD de cierta US20180121386A1 (1) de AMD pienso que lo mejor es una explicación visual y una serie de definiciones básicas. ¿Que es una unidad SIMD? En primer lugar hemos de tener en cuenta que es una organización de ALU (LUA en Español) donde podemos realizar de manera simultanea la misma instrucción a diferentes operandos/datos al mismo tiempo en paralelo.

345px-SIMD.svg

Las unidades SIMD son llamadas también Vector Units, por ejemplo a nivel de las CPUs la unidad AVX de lo chips x86-64 es una unidad SIMD. Se ha de tener en cuenta además que la cantidad de operandos con los que tenga que trabajar es variable para se ha de entender que la unidad SIMD realiza misma misma instrucción para todos ellos.

Al nivel de las actuales GPUs de AMD las llamadas Compute Units disponen de 4 unidades SIMD cada una.

kaveri-14b

Cada unidad SIMD tiene su propio set de registros (data pool) pero tienen en común el mismo pozo de instrucciones, es decir, cada una de las 16 ALUs que componen la unidad SIMD harán la misma instrucción. Ahora bien, en AMD las instrucciones son distribuidas en forma de olas con 64 elementos cada uno, no son 64 instrucciones sino que son 64 instrucción+dato, a esto se le llama kernel y el planificador de la CU organiza el conjunto de kernels (hasta 16) por el mismo tipo de instrucción a medida que van llegando. El siguiente gráfico explica a la perfección cual es el proceso de como se ejecuta una ola/wavefront en una unidad SIMD.

El tamaño y organización ideales de un Wavefront es el siguiente:

wavefrontgraphic

Cada color represente una instrucción, cada instrucción se resuelve en un ciclo y tenemos todas las ALUs funcionando y estando ocupadas, voy a tomar solo el escenario ideal para no liar mucho el tema. Esto es con la unidad SIMD normal… ¿Pero que ocurre con la unidad Super-SIMD? Pues ocurre que en vez de tener una sola cadena/array de ALUs…

FIG. 1A

Tenemos dos de ellas compartiendo el mismo pozo de registros

FIG1B

Normalmente deberíamos tener el doble de pozos de registros y dos redes de distribución de operandos, una para cada ALU pero AMD con tal de no duplicar hardware lo que sugiere en la patente de la SuperSIMD es que las olas en vez de almacenar en cada ola un kernel de instrucción+dato se almacenen 2 instrucciones y sus correspondientes datos, a eso se le llama VLIW y en el caso que nos ocupa se le llama VLIW2 y es una técnica de paralelismo que evita duplicar toda la unidad de control previa a una serie de ALUs, de tal manera que seguimos teniendo una ola de 64 elementos, no la hemos hecho más grande realmente y el mecanismo de distribución general de la GPU tampoco lo hemos hecho el doble de complejo.

¿Y que ganamos teniendo dos ALUs? Pues el hecho de realizar el doble de operaciones por ciclo sin duplicar la cantidad de Compute Units y sin tener que duplicar el front-end de la GPU y sobrecomplicarlo por ello. es el New Operand Delivery Network el que rompe el VLIW2 en dos instrucciones y envia cada una a una ALU distinta. Puede hacerlo sin necesidad de ayuda porque en una GPU la longitud de las instrucciones es siempre la misma o se agrupa en grupos donde la longitud es la misma siempre entre todas las instrucciones de su grupo. En el caso de AMD tenemos el siguiente tipo de instrucciones:

  • Simples: Se realizan en 1 ciclo por instrucción, dado que una ola tarda en realizarse 4 instrucciones esto son 4 ciclos de reloj por ola.
  • Complejas: Se realizan en 4 ciclos por instrucción, dado que una ola tarda en realizarse 4 instrucciones esto son 16 ciclos de reloj por ola.
  • Salto: Se realizan unicamente en la unidad escalar de la ALU, son las más lentas de todas y necesitan unos 16 ciclos en el cual todas las unidades SIMD de la CU están ocupadas.

Al final la nueva Compute Unit al completo queda de la siguiente manera:

fig3navi

Por lo que es una Compute Unit normal y corriente, pero con los siguientes cambios:

  • El SQ/Scheduler/Planificador queda complementente igual que la CU estándar. Puede operar hasta 40 olas distintas compuestas cada una por 64 kernels en VLIW2.
  • De cada una de las unidades Super-SIMD ya he relatado su funcionamiento más arriba.
  • 256 operaciones (FMADD) por ciclo de reloj en vez de las 128 de la CU estandar (FP32).
  • La Local Data Storage/LDS pasa a tener 64KB a unos 128KB
  • Pasamos a tener 2 unidades de texturas (TATD) por lo que por Compute Unit ahora en vez de procesarse 4 texeles por ciclo de reloj se procesan 8.
  • 2 Pozos de Cache de Datos/Texturas en vez de 1.

La cual es más cercana a la de la actual Compute Unit.

MiniCU.PNG

Esta organización alternativa es más simple y tiene la misma capacidad de calculo que la CU estándar de las GCN, a diferencia de la Super-CU de la ilustración de arriba:

  • El SQ/Scheduler/Planificador es más simple. Puede operar hasta 40 olas distintas compuestas cada una por 64 kernels en VLIW2.
  • De cada una de las 2 unidades Super-SIMD ya he relatado su funcionamiento más arriba.
  • 128 operaciones (FMADD) por ciclo de reloj las mismas que la CU estandar (FP32).
  • La Local Data Storage/LDS es de 64KB
  •  1 sola unidad de texturas, 4 texeles por ciclo de reloj.
  • 1 Cache de datos/texturas L1.

¿Que diferencia tiene respecto a la clásica Compute Unit? Se ha de entender que el limite de las 64 CUs tiene que ver con el mecanismo de los datos y tener en cuenta que la cantidad de bifurcaciones y caminos para alimentar unas 64 CUs es enorme, pero el limite no esta en el número de CUs sino en el número olas que se pueden distribuir. ¿Y que unidad se encarga de esto a nivel global para todas las CUs?

GPUScheduler

El Workgroup Distributor es el que se encarga de ir distribuyendo las olas/wavefronts a las Compute Units que esten libres. El limite no esta por tanto en la cantidad de Compute Units sino en la cantidad de olas a distribuir pero hemos hecho con el uso de kernels en VLIW2 el poder colocar el doble de instrucciones y con ello realmente estamos duplicando la cantidad de tareas que enviamos. Es decir, es como si el Workgroup Distributor pudiese repartir no se… 1000 paquetes máximo al día y nos interese colocar 2000 paquetes de 500g. ¿Que hacemos? Pues le colocamos 1000 paquetes de 1Kg y asunto concluido. Gracias a ello en el caso de utilizar las Super-CU del segundo ejemplo podemos superar la cantidad de Compute Units disponibles pero en el caso del primer ejemplo no harian falta tantas por el hecho que cada una tendría el doble de capacidad de procesamiento que una Compute Unit normal.

Eso es todo, teneis los comentarios de esta misma entrada y el canal de Discord si tenéis alguna duda sobre la entrada.