tutorial programming cuda

programming - CUDA Blocks & Warps



cuda toolkit (3)

Busco ser más eficiente para reducir mi tiempo de ejecución y, por lo tanto, necesito saber exactamente cuántos subprocesos / deformaciones / bloques pueden ejecutarse a la vez en paralelo.

En resumen, el número de subprocesos / deformaciones / bloques que pueden ejecutarse simultáneamente depende de varios factores. La Guía de Buenas Prácticas de CUDA C tiene una reseña de las Optimizaciones de la Configuración de Ejecución que explica estos factores y proporciona algunos consejos para razonar sobre cómo dar forma a su aplicación.

Ok, sé que las preguntas relacionadas se han hecho una y otra vez y leí casi todo lo que encontré sobre esto, pero las cosas aún no están claras. Probablemente también porque encontré y leí cosas que se contradicen entre sí (tal vez porque, al ser de tiempos diferentes, se referían a dispositivos con diferentes capacidades informáticas, entre las cuales parece haber bastante espacio). Busco ser más eficiente para reducir mi tiempo de ejecución y, por lo tanto, necesito saber exactamente cuántos subprocesos / deformaciones / bloques pueden ejecutarse a la vez en paralelo. También estaba pensando en generalizar esto y calcular un número óptimo de subprocesos y bloques para pasar a mi kernel basándose solo en el número de operaciones que sé que tengo que hacer (para programas más simples) y las especificaciones del sistema.

Tengo un GTX 550Ti, por cierto con capacidad de cálculo 2.1. 4 SMs x 48 núcleos = 192 núcleos CUDA.

Ok, lo que no está claro para mí es:

¿Se puede ejecutar más de 1 bloque una vez (en paralelo) en un multiprocesador (SM)? Leí que se pueden asignar hasta 8 bloques a un SM, pero nada sobre cómo se ejecutan. Por el hecho de que mi número máximo de subprocesos por SM (1536) es apenas mayor que mi número máximo de subprocesos por bloque (1024), creo que los bloques no se ejecutan en paralelo (¿tal vez uno y medio?). O al menos no si tengo un número máximo de hilos en ellos. Además, si configuro el número de bloques a, digamos 4 (mi número de SM), ¿se enviarán a un SM diferente cada uno? O realmente no puedo controlar cómo se distribuye todo esto en el hardware y luego este es un punto discutible, mi tiempo de ejecución variará según los caprichos de mi dispositivo ...

En segundo lugar, sé que un bloque dividirá sus hilos en grupos de 32 hilos que se ejecutan en paralelo, llamados deformaciones. Ahora estas deformaciones (suponiendo que no tienen ninguna relación entre sí) se pueden ejecutar en paralelo también? Debido a que en la arquitectura Fermi se indica que se ejecutan 2 deformaciones simultáneamente, enviando una instrucción de cada deformación a un grupo de 16 (?) Núcleos, mientras que en otro lugar leo que cada núcleo maneja una deformación, lo que explicaría los 1536 hilos máximos ( 32 * 48) pero parece un poco mucho. ¿Puede 1 CUDA core manejar 32 hilos simultáneamente?

En una nota más simple, lo que pregunto es: (por ejemplo) si quiero sumar 2 vectores en un tercero, ¿qué longitud debo darles (nr de operaciones) y cómo debo dividirlos en bloques e hilos para mi dispositivo funciona simultáneamente (en paralelo) a plena capacidad (sin tener núcleos inactivos o SM).

Lo siento si esto fue preguntado antes y no lo entendí o no lo vi. Espero que me pueda ayudar. ¡Gracias!


La distribución y la ejecución paralela del trabajo están determinadas por la configuración de lanzamiento y el dispositivo. La configuración de inicio indica las dimensiones de la cuadrícula, las dimensiones del bloque, los registros por subproceso y la memoria compartida por bloque. Según esta información y el dispositivo, puede determinar la cantidad de bloques y deformaciones que se pueden ejecutar en el dispositivo simultáneamente. Cuando se desarrolla un kernel, por lo general, se observa la proporción de deformaciones que pueden estar activas en el SM con el número máximo de deformaciones por SM para el dispositivo. Esto se llama la ocupación teórica. La Calculadora de ocupación CUDA se puede utilizar para investigar diferentes configuraciones de lanzamiento.

Cuando se inicie una cuadrícula, el distribuidor de trabajo informático rasterizará la cuadrícula y distribuirá los bloques de hilos a los SM y los recursos de SM se asignarán para el bloque de hilos. Se pueden ejecutar múltiples bloques de hilos simultáneamente en el SM si el SM tiene recursos suficientes.

Para lanzar un warp, el SM asigna el warp a un programador de warp y asigna registros para el warp. En este punto, la deformación se considera una deformación activa.

Cada programador de warp gestiona un conjunto de warp (24 en Fermi, 16 en Kepler). Las deformaciones que no están bloqueadas se denominan deformaciones elegibles. En cada ciclo, el programador de deformación selecciona una deformación elegible y emite las instrucciones para la deformación a las unidades de ejecución, como las unidades int / fp, las unidades de punto flotante de doble precisión, las unidades de función especial, las unidades de resolución de rama y las unidades de almacenamiento de carga. Las unidades de ejecución están canalizadas, lo que permite que muchas urdimbres tengan 1 o más instrucciones en vuelo en cada ciclo. Las deformaciones pueden detenerse en la obtención de instrucciones, dependencias de datos, dependencias de ejecución, barreras, etc.

Cada kernel tiene una configuración de lanzamiento óptima diferente. Herramientas como Nsight Visual Studio Edition y NVIDIA Visual Profiler pueden ayudarlo a ajustar su configuración de inicio. Le recomiendo que intente escribir su código de manera flexible para poder probar varias configuraciones de inicio. Comenzaría con una configuración que le ofrezca al menos un 50% de ocupación, luego intente aumentar y disminuir la ocupación.

Respuestas a cada pregunta

P: ¿Se puede ejecutar más de 1 bloque EN UNA VEZ (en paralelo) en un multiprocesador (SM)?

Sí, el número máximo se basa en la capacidad de cálculo del dispositivo. Consulte la Tabla 10. Especificaciones técnicas por capacidad de cálculo: Número máximo de bloques de residentes por multiprocesador para determinar el valor. En general, la configuración de lanzamiento limita el valor del tiempo de ejecución. Consulte la calculadora de ocupación o una de las herramientas de análisis de NVIDIA para obtener más detalles.

P: Por el hecho de que mi número máximo de subprocesos por SM (1536) es apenas mayor que mi número máximo de subprocesos por bloque (1024), creo que los bloques no se ejecutan en paralelo (¿quizás 1 y medio?).

La configuración de lanzamiento determina el número de bloques por SM. La proporción de subprocesos máximos por bloque y máximo de subprocesos por SM se establece para permitir al desarrollador una mayor flexibilidad en la forma en que realizan las particiones.

P: Si configuro el número de bloques a, digamos 4 (mi número de SM), ¿se enviarán a un SM diferente cada uno? O realmente no puedo controlar cómo se distribuye todo esto en el hardware y luego este es un punto discutible, mi tiempo de ejecución variará según los caprichos de mi dispositivo ...

Tienes un control limitado de la distribución del trabajo. Puede controlar esto de forma artificial limitando la ocupación asignando más memoria compartida, pero esta es una optimización avanzada.

P: En segundo lugar, sé que un bloque dividirá los subprocesos en grupos de 32 subprocesos que se ejecutan en paralelo, llamados deformaciones. ¿Ahora estas deformaciones (suponiendo que no tienen ninguna relación entre sí) también se pueden ejecutar en paralelo?

Sí, las deformaciones pueden correr en paralelo.

P: Porque en la arquitectura Fermi se establece que 2 deformaciones se ejecutan simultáneamente

Cada Fermi SM tiene 2 programadores de deformaciones. Cada programador de warp puede enviar instrucciones para 1 warp en cada ciclo. La ejecución de la instrucción está canalizada, por lo que muchas urdimbres pueden tener una o más instrucciones en vuelo en cada ciclo.

P: Enviar una instrucción de cada urdimbre a un grupo de 16 (?) Núcleos, mientras que en otro lugar leo que cada núcleo maneja una urdimbre, lo que explicaría los 1536 hilos máximos (32x48) pero parece un poco demasiado. ¿Puede 1 CUDA core manejar 32 hilos simultáneamente?

Sí. Los núcleos CUDA son el número de unidades de ejecución de entero y punto flotante. El SM tiene otros tipos de unidades de ejecución que enumeré anteriormente. El GTX550 es un dispositivo CC 2.1. En cada ciclo, un SM tiene el potencial de despachar a lo sumo 4 instrucciones (128 hilos) por ciclo. Dependiendo de la definición de ejecución, el total de subprocesos en vuelo por ciclo puede variar desde cientos hasta miles.


Para mí, uno de los conceptos que se tomaron en cuenta fue la eficiencia del soporte de hardware para el cambio de contexto en el chip CUDA.

En consecuencia, se produce un cambio de contexto en cada acceso a la memoria, lo que permite que los cálculos se realicen en muchos contextos alternativamente, mientras que los otros esperan en los accesos a la memoria. Una de las formas en que las arquitecturas de GPGPU logran el rendimiento es la capacidad de paralelizar de esta manera, además de paralelizar en los núcleos de múltiples.

El mejor rendimiento se logra cuando ningún núcleo está esperando un acceso a la memoria, y se logra al contar con los contextos suficientes para garantizar que esto suceda.