OpenCL: desafíos reales - página 7

 

1) Pragmas es un requisito de soporte en tiempo de compilación, no la activación del soporte en sí mismo (como pareces pensar). Así que cl_khr_fp64 ya está involucrado si su vises lo soporta.

2) ¿Y si el tamaño del array cambia en tiempo de ejecución? Por supuesto, se puede hacer en este código en particular, pero no mejorará la situación.

Permítanme decirles de inmediato que estaba perfilando en AMD CodeXL:

3) Si tomamos sólo el tiempo de computación del propio núcleo, cualquier tarea paralela en la GPU se beneficiará de la utilización de más núcleos en la CPU. Así que incluso 8 tareas son suficientes para acelerar las cosas.

4) Yo mismo tengo muchas preguntas sobre la fórmula de cálculo local. La mayor ganancia tuvo lugar cuando en work_dim=1 repartí las tareas entre todos los núcleos del widget y esto es UNITS.

¿Y por qué se divide el tamaño del buffer en general, cuando se debería dividir el número de sus elementos? - lo que realmente hice.

Mathemat: En resumen: ¿qué tiene que hacer su código?

Demostrar que la fase de preparación de los cálculos no es instantánea y que la transferencia de búferes lleva mucho tiempo, pone en duda la viabilidad de utilizar OpenCL incluso para tareas alimentadas.

También muestra que la CPU no está seleccionada en el probador.

 
Roffild:

Se demuestra que la fase de preparación de los cálculos no es instantánea y la transferencia de búferes lleva mucho tiempo, lo que pone en duda la viabilidad de utilizar OpenCL incluso para tareas exageradas.

Es decir, es una tontería gritar por ello; medirlo, en cambio, es otra cosa; puede ser útil en la práctica.

También muestra que la CPU no está seleccionada en el probador.

Tal vez esté justificado, pero tal vez sea un exceso de seguridad. De todos modos, estoy seguro de que se hizo conscientemente para garantizar la eficiencia del proceso de pruebas en sí, o más bien la optimización (ya que es multihilo). Aquí las posibilidades de lograr la inclusión pueden aparecer si la noción de pruebas y la optimización están clara y completamente separadas (en el nivel de la política de los partidos), es decir, se definen como diferentes tipos lógicos de uso de los probadores. Con el correspondiente soporte de software (oficialmente diferente). (Esto sería bueno en muchos sentidos, y soy partidario desde hace mucho tiempo de esa separación/distinción. Hasta botones diferentes para empezar a optimizar y probar).

Teóricamente, la selección de la CPU podría entonces permitirse durante las pruebas y desestimarse durante la optimización (esto es correcto).

 
Roffild: 1) Los pragmas son un requisito de soporte en tiempo de compilación, no una activación del soporte en sí (como pareces creer). Es decir, cl_khr_fp64 ya interviene si la víscera lo soporta.

Sí, me pasé con el pragma. Si vas a seguir trabajando en tu widget y no pasas el código a nadie más, no hay problema. Pero si alguien quiere leerlo en una tarjeta Barts (digamos, 6870), habrá problemas. El código del kernel intentará ejecutarse sin mostrar errores.

4) Yo también tengo muchas dudas sobre la fórmula de cálculo de Local. La mayor ganancia fue cuando work_dim=1 reparte las tareas entre todos los núcleos del widget, y esto es UNITS.

No necesariamente. A menudo es mucho más útil aumentar el trabajo en el propio núcleo. Se trata de igualar la sobrecarga asociada a la transferencia de datos.

Y su UNITS es sólo un número de motores SIMD. Según la documentación,

local_work_size[] establece un subconjunto de tareas que serán ejecutadas por el núcleo del programa OpenCL especificado. Su dimensión es igual a work_items[]y permite cortar el subconjunto total de tareas en subconjuntos más pequeños sin residuo de división . Dehecho, el tamaño de la matriz local_work_size[] debe elegirse de manera que el conjunto de tareas globales work_items[] se corte en subconjuntos más pequeños. En este ejemplo,local_work_size[3]={10, 10, 10} servirá , ya quework_items[40, 100, 320] se puede ensamblar desde el array local_items[10, 10, 10] sin ningún residuo .

El número de motores SIMD es una constante estrictamente de hardware que no tiene que dividir la tarea global en absoluto.

Pero primero hay que evaluar adecuadamente el problema global en sí.

Sobre la CPU en el probador - ya veo, estoy convencido.

 
MetaDriver:

Esto no es absolutamente nada nuevo. Es una tontería gritar sobre ello, pero medirlo es otra cosa; puede ser útil en la práctica.

Excepto que por alguna razón tuve que tomar estas medidas... Cuando se lee "hay un retraso en la transmisión" no se tiene idea de la magnitud del mismo.

Mathemat: Y su UNITS es sólo un número de motores SIMD. Según la documentación,

El número de motores SIMD es una constante estrictamente de hardware, que no tiene que dividir la tarea global en absoluto.

Mejor usemos la documentación oficial:

CL_DEVICE_MAX_COMPUTE_UNITS cl_uint Número de unidades de cálculo paralelas en el dispositivo OpenCL. Un grupo de trabajo se ejecuta en una única unidad de cálculo. El valor mínimo es 1.
local_work_size.
Apunta a un array de valores sin signo work_dim que describen el número de elementos de trabajo que componen un grupo de trabajo (también denominado tamaño del grupo de trabajo) que ejecutará el núcleo especificado por el kernel.
Así que mis conclusiones son correctas y confirmadas por la ejecución de AMD CodeXL
 

La cuestión es otra. Llama a tus barriles de unidades, pero el hecho es que las unidades en tu código no dividen la tarea global en enteros (el mío ciertamente no lo hace: 240/28 no es entero; el tuyo también, ya que tienes unidades=18). Esto es un error.

Y segundo, aquí y ahora estás trabajando con OpenCL para MQL5 (bueno, no es correcto, pero me has pillado); que, al fin y al cabo, es un OpenCL diferente al de Khronos.

P.D. Yo no he creado el hipervínculo; lo he conseguido por mi cuenta :)

Roffild:
CL_DEVICE_MAX_COMPUTE_UNITS cl_uint Número de unidades de cálculo paralelas en el dispositivo OpenCL. Un grupo de trabajo se ejecuta en una única unidad de cálculo. El valor mínimo es 1.

Véase la definición de "unidades de cálculo" en otras fuentes.

Por cierto, aquí hay una tabla de mi segundo artículo. Estaría bien que entendieras todas estas unidades de cálculo (18), núcleos de flujo (288), elementos de procesamiento (1440), frentes de onda máximos/GPU (496) y elementos de trabajo/GPU (31744). Todavía no lo he descubierto.


 
Mathemat:

La cuestión es otra. Llama a tus barriles de unidades, pero el hecho es que las unidades en tu código no dividen la tarea global en enteros (el mío ciertamente no lo hace: 240/28 no es entero; el tuyo también, ya que tienes unidades=18). Esto es un fallo.

Entonces, ¿por qué has basado el número de bytes en 240? Puede que tú puedas hacerlo, pero la tarjeta gráfica no. Así que 240/8 = 30 dobles.

240 bytes es el tamaño del buffer completo de 30 dobles.

Y "elegir un divisor entero" es sólo una recomendación de la documentación oficial. Y esa recomendación no funciona perfectamente.

Y lo de UNITS no es mío, es sólo un consejo de los foros de OpenCL. Lo he probado y he conseguido la máxima velocidad...

Matemáticas:

Y lo segundo: aquí y ahora estás trabajando con OpenCL para MQL5 (bueno, no es correcto, pero me has pillado) donde al fin y al cabo es un OpenCL diferente al de Khronos.

¿Y cuál es el "otro"?

Estás confundiendo implementaciones propietarias y simples envoltorios. OpenCL MQL es sólo una envoltura sobre la API OpenCL de Khronos. Sobre la diferencia entre OpenCL MQL y Khronos.

 
Mathemat: Por cierto, aquí está la tabla de mi segundo artículo. Estaría bien que entendieras todas estas unidades de cálculo (18), núcleos de flujo (288), elementos de procesamiento (1440), frentes de onda máximos/GPU (496) y elementos de trabajo/GPU (31744). Todavía no lo he descubierto.

unidades de cálculo es el número de tareas simultáneas que se ejecutan.

Los frentes de onda máximos/GPU (496) y los elementos de trabajo/GPU (31744) son la cola a ejecutar.

AMD CodeXL ya tiene una respuesta a todas estas preguntas.

 
Roffild:

unidades de cálculo es el número de tareas simultáneas que se ejecutan.

Los frentes de onda máximos/GPU (496) y los elementos de trabajo/GPU (31744) son la cola de ejecución.

AMD CodeXL puede ayudarle por fin: responde a todas estas preguntas.

Quizás no entiendo algo, lo siento. ¿Pero conoces a Alexey personalmente? Pero desde el lado no se ve como..... hablas con demasiado descaro, más inteligente que otros... ser inteligente no es un pecado, presumir de ello entre hermanos de espíritu es vergonzoso sin embargo...

 

Soy un tipo sencillo y respondo al grano.

Si realmente quieres entender OpenCL y no sólo suponerlo, tendrás que poner AMD CodeXL y crear tu propio wrapper de C/C++.

Puedo publicar mi wrapper, pero tiene algunas líneas ilógicas debido a mi falta de práctica en C/C++.

 
Roffild: Entonces, ¿por qué has tomado 240 bytes como número base? Tú puedes hacerlo, pero la tarjeta de vídeo no. Así que 240/8 = 30 dobles.

240 bytes es el tamaño del buffer completo de 30 dobles.

Mira tu propio código:

uint units = (uint)CLGetInfoInteger(hcontext, CL_DEVICE_MAX_COMPUTE_UNITS);
uint global_work_offset[] = {0};
uint global_work_size[1];
uint local_work_size[1];
global_work_size[0] = ArraySize(price);
Print( "Глобальная задача = ", global_work_size[0] );  /// Это я добавил, вышло 240. Но это и так легко подсчитать: 30*double = 240
local_work_size[0] = global_work_size[0] / units;

Además, en la última línea, tú mismo divides 240 entre 18 (son unidades para tu mapa).

Y "recoger todo el divisor" es sólo una recomendación de la documentación oficial. Y esta recomendación no funciona perfectamente.

Estamos trabajando con MQL5 OpenCL. Me refiero a la documentación de nuestro sitio web. Por supuesto, también estoy mirando a Khronos.

Y en cuanto a las UNIDADES, no son palabras mías, sino algunos consejos de los foros de OpenCL. Lo he probado y he conseguido la máxima velocidad...

Bueno, he conseguido la máxima velocidad con diferentes parámetros. ¿Y qué?

Vamos a dar una idea aproximada. 18 tareas que se ejecutan simultáneamente en las moscas de la GPU es lo máximo que se puede hacer en 4-5 cadenas de CPU. Y una CPU en emulación x86 puede organizar muchos más hilos. Al menos si se trata de Intel. Mi antiguo Pentium G840 (2 núcleos) daba una aceleración de unas 70 veces, ¡en dos unidades! Por no hablar de lo que mi actual... i7, por así decirlo.

Una tarea bien paralelizada (echa un vistazo a los scripts de MetaDriver de la primera rama ocl) permite alcanzar una velocidad de hasta 1000 o más en la GPU (en comparación con 1 hilo en la CPU en MQL5). Si no lo encuentras, puedo descargarlo para que lo pruebes en tu tarjeta.

Si realmente quieres entender OpenCL y no sólo adivinarlo, tendrás que poner AMD CodeXL y crear tu propio wrapper de C/C++.

Vale, le echaré un vistazo, gracias.

Razón de la queja: