tutorial - gpu cuda programming
CUDA: ¿Cuántos hilos concurrentes en total? (3)
Tengo una GeForce GTX 580, y quiero hacer una declaración sobre la cantidad total de hilos que (idealmente) se pueden ejecutar en paralelo, para comparar con 2 o 4 CPU multi-core.
deviceQuery me da la siguiente información posiblemente relevante:
CUDA Capability Major/Minor version number: 2.0
(16) Multiprocessors x (32) CUDA Cores/MP: 512 CUDA
Maximum number of threads per block: 1024
Creo que escuché que cada núcleo CUDA puede ejecutar un warp en paralelo, y que un Warp tiene 32 hilos. ¿Sería correcto decir que la tarjeta puede ejecutar 512 * 32 = 16384 hilos en paralelo entonces, o estoy muy lejos y los núcleos CUDA de alguna manera no funcionan en paralelo?
Hay ciertas trampas en las que puede caer al hacer esa comparación con CPU de 2 o 4 núcleos:
El número de subprocesos simultáneos no coincide con la cantidad de subprocesos que realmente se ejecutan en paralelo. Por supuesto, puede iniciar 24576 subprocesos al mismo tiempo en GTX 580, pero el valor óptimo es en la mayoría de los casos inferior.
¡Una CPU de 2 o 4 núcleos puede tener muchos hilos concurrentes arbitrarios! Del mismo modo que con GPU, desde algún punto agregar más hilos no ayudará, o incluso puede ralentizar.
Un "núcleo CUDA" es una unidad de procesamiento escalar única, mientras que el núcleo de la CPU suele ser una cosa más grande, que contiene, por ejemplo, una unidad SIMD de 4 amplios. Para comparar manzanas con manzanas, debe multiplicar la cantidad de núcleos de CPU publicitados por 4 para que coincida con lo que NVIDIA llama núcleo.
La CPU admite hyperthreading, lo que permite que un solo núcleo procese 2 subprocesos simultáneamente de forma ligera. Debido a eso, un sistema operativo puede ver 2 veces más "núcleos lógicos" que los núcleos de hardware.
Para resumir: para una comparación justa, su CPU de 4 núcleos puede ejecutar 32 "hilos escalares" concurrentemente, debido a SIMD y hyperthreading.
La GTX 580 puede tener 16 * 48 warps simultáneos (32 hilos cada uno) que se ejecutan a la vez. Eso es 16 multiprocesadores (SM) * 48 urdimbres residentes por SM * 32 hilos por urdimbre = 24.576 hilos.
No confundas la concurrencia y el rendimiento. El número anterior es la cantidad máxima de hilos cuyos recursos se pueden almacenar en el chip simultáneamente: el número que puede ser residente . En términos de CUDA también llamamos a esta ocupación máxima. El hardware cambia constantemente entre urdimbres para ayudar a cubrir u "ocultar" la latencia (grande) de los accesos a la memoria, así como también la (pequeña) latencia de las tuberías aritméticas.
Si bien cada SM puede tener 48 urdimbres residentes, solo puede emitir instrucciones de un número pequeño (en promedio, entre 1 y 2 para GTX 580, pero depende de la combinación de instrucciones del programa) de urdimbres en cada ciclo de reloj.
Por lo tanto, probablemente sea mejor que compare el rendimiento, que está determinado por las unidades de ejecución disponibles y por la forma en que el hardware es capaz de realizar múltiples problemas. En GTX580, hay 512 unidades de ejecución FMA, pero también unidades enteras, unidades de funciones especiales, unidades de instrucciones de memoria, etc., que pueden ser de doble emisión (es decir, emiten instrucciones independientes de 2 warps simultáneamente) en varias combinaciones.
Sin embargo, tomar en cuenta todo lo anterior es demasiado difícil, por lo que la mayoría de las personas se compara en dos parámetros:
- Peak GFLOP / s (que para GTX 580 es de 512 unidades FMA * 2 fracasos por FMA * 1544e6 ciclos / segundo = 1581.1 GFLOP / s (precisión simple))
- Rendimiento medido en la aplicación que le interesa.
La comparación más importante siempre es el tiempo de reloj de pared medido en una aplicación real.
Me doy cuenta de que esto es un poco tarde, pero pensé que ayudaría de todos modos. Desde la página 10, el documento técnico de arquitectura de CUDA Fermi :
Cada SM presenta dos planificadores de warp y dos unidades de despacho de instrucciones, lo que permite emitir dos warps y ejecutarlos al mismo tiempo.
Para mí, esto significa que cada SM puede tener 2 * 32 = 64 hilos ejecutándose simultáneamente. No sé si eso significa que la GPU puede tener un total de 16 * 64 = 1024 hilos ejecutándose simultáneamente.