parallel-processing opencl

parallel processing - OpenCL: concepto de grupo de trabajo



parallel-processing (4)

El uso de los grupos de trabajo permite una mayor optimización para los compiladores del kernel. Esto se debe a que los datos no se transfieren entre grupos de trabajo. Dependiendo del dispositivo OpenCL utilizado, puede haber cachés que pueden usarse para que las variables locales den como resultado accesos de datos más rápidos. Si solo hay un grupo de trabajo, las variables locales serían las mismas que las variables globales, lo que conduciría a accesos de datos más lentos.

Además, por lo general, los dispositivos OpenCL usan extensiones de datos múltiples de instrucción única (SIMD) para lograr un buen paralelismo. Un grupo de trabajo se puede ejecutar en paralelo con las extensiones SIMD.

Should a Work-Group exactly map to a physical core ?

Creo que, la única forma de encontrar el tamaño más rápido para un grupo de trabajo, es probar diferentes tamaños de grupos de trabajo. También es posible consultar el CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE desde el dispositivo con clGetKernelWorkGroupInfo . El tamaño más rápido debe ser múltiplo de eso.

Can work-groups synchronize or is that even needed ?

Los grupos de trabajo no se pueden sincronizar . De esta manera no hay dependencias de datos entre ellos y también se pueden ejecutar de forma secuencial, si se considera que es la forma más rápida de ejecutarlos. Para lograr el mismo resultado, que la sincronización entre grupos de trabajo, el núcleo debe dividirse en varios núcleos. Las variables pueden ser transferidas entre los kernels con buffers.

Realmente no entiendo el propósito de los Grupos de Trabajo en OpenCL.

Entiendo que son un grupo de elementos de trabajo (supuestamente, hilos de hardware), los cuales se ejecutan en paralelo.

Sin embargo, ¿por qué existe esta necesidad de una subdivisión más gruesa? ¿No estaría bien tener solo la cuadrícula de hilos (y, de hecho , solo un WG)?

¿Debe un grupo de trabajo asignarse exactamente a un núcleo físico? Por ejemplo, se dice que la tarjeta TESLA c1060 tiene 240 núcleos. ¿Cómo se asignarían los grupos de trabajo a esto?

Además, según tengo entendido, los elementos de trabajo dentro de un grupo de trabajo se pueden sincronizar gracias a las vallas de memoria. ¿Se pueden sincronizar los grupos de trabajo o es incluso necesario? ¿Se hablan entre sí a través de la memoria compartida o es solo para elementos de trabajo (no estoy seguro en este caso)?


Parte de la confusión aquí creo que se reduce a la terminología. Lo que las personas de GPU a menudo llaman núcleos, en realidad no lo son, y lo que las personas de GPU a menudo llaman hilos son solo en cierto sentido.

Los núcleos Un núcleo, en términos de marketing de GPU, puede referirse a algo así como un núcleo de CPU, o puede referirse a un solo carril de una unidad SIMD; en efecto, una CPU x86 de un solo núcleo serían cuatro núcleos de este tipo más simple. Es por eso que los recuentos de núcleos de GPU pueden ser tan altos. No es realmente una comparación justa, hay que dividir entre 16, 32 o un número similar para obtener un recuento de núcleos más directamente comparable.

Elementos de trabajo Cada elemento de trabajo en OpenCL es un hilo en términos de su flujo de control y su modelo de memoria. El hardware puede ejecutar múltiples elementos de trabajo en un solo hilo, y puede imaginarse fácilmente esto imaginando cuatro elementos de trabajo de OpenCL que operan en los carriles separados de un vector SSE. Sería simplemente el engaño del compilador lo que logra eso, y en las GPU tiende a ser una mezcla de engaño del compilador y asistencia de hardware. OpenCL 2.0 realmente expone este concepto de subproceso de hardware subyacente a través de subgrupos, por lo que hay otro nivel de jerarquía con el que lidiar.

Grupos de trabajo Cada grupo de trabajo contiene un conjunto de elementos de trabajo que deben poder avanzar en presencia de barreras. En la práctica, esto significa que es un conjunto, todos cuyos estados pueden existir al mismo tiempo, de modo que cuando se encuentra una primitiva de sincronización, existe una pequeña sobrecarga al cambiar entre ellos y hay una garantía de que el cambio es posible.

Un grupo de trabajo debe asignarse a una sola unidad de cómputo, lo que significa de manera realista que todo el grupo de trabajo encaja en una única entidad que las personas de la CPU llamarían un núcleo: CUDA lo llamaría multiprocesador (según la generación), AMD una unidad de cómputo y otros tienen nombres diferentes. Esta localidad de ejecución conduce a una sincronización más eficiente, pero también significa que el conjunto de elementos de trabajo puede tener acceso a unidades de memoria construidas localmente. Se espera que se comuniquen con frecuencia, o no se usarían barreras, y para hacer que esta comunicación sea eficiente, puede haber cachés locales (similares a una CPU L1) o memorias de bloc de notas (memoria local en OpenCL).

Mientras se usen barreras, los grupos de trabajo pueden sincronizarse internamente, entre elementos de trabajo, utilizando la memoria local o utilizando la memoria global. Los grupos de trabajo no pueden sincronizarse entre sí y la norma no garantiza el progreso hacia adelante de los grupos de trabajo entre sí, lo que hace que la creación de primitivas de bloqueo y sincronización portátiles sea efectivamente imposible.

Mucho de esto se debe a la historia más que al diseño. El hardware de la GPU ha sido diseñado durante mucho tiempo para construir hilos vectoriales y asignarlos a unidades de ejecución de una manera que procesa los triángulos de manera óptima. OpenCL deja de generalizar que el hardware sea útil para otras cosas, pero no lo generaliza tanto que se vuelve ineficiente de implementar.


Una de las ventajas de los grupos de trabajo es que permiten el uso de la memoria local compartida como un caché definido por el programador. Un valor leído de la memoria global se puede almacenar en la memoria local compartida del grupo de trabajo y luego se puede acceder rápidamente por cualquier elemento de trabajo en el grupo de trabajo. Un buen ejemplo es el juego de la vida: cada célula depende de sí misma y de las 8 que la rodean. Si cada elemento de trabajo leyera esta información, tendría 9x lecturas de memoria global. Al usar grupos de trabajo y memoria local compartida, puede acercarse a las lecturas de memoria global 1x (solo enfoque ya que hay lecturas redundantes en los bordes).


Ya hay muchas respuestas correctas, para una mayor comprensión de la terminología de OpenCL, este documento en realidad describe muy bien todos los conceptos.