programar - opencl vs opengl
OpenGL vs. OpenCL, ¿cuál elegir y por qué? (10)
¿Qué características hacen que OpenCL sea único para elegir sobre OpenGL con GLSL para cálculos? A pesar de la terminología gráfica y los tipos de datos prácticos, ¿hay alguna advertencia real para OpenGL?
Por ejemplo, la evaluación de la función paralela se puede hacer renderizando a en una textura usando otras texturas. Las operaciones de reducción se pueden realizar mediante la representación iterativa de texturas cada vez más pequeñas. Por otro lado, el acceso de escritura aleatorio no es posible de ninguna manera eficiente (la única manera de hacerlo es renderizando triángulos mediante datos de vértices basados en texturas). ¿Es esto posible con OpenCL? ¿Qué más no es posible con OpenGL?
¿Qué características hacen que OpenCL sea único para elegir sobre OpenGL con GLSL para cálculos? A pesar de la terminología gráfica y los tipos de datos prácticos, ¿hay alguna advertencia real para OpenGL?
Sí, es una API de gráficos. Por lo tanto, todo lo que hagas debe formularse según esos términos. Tienes que empaquetar tus datos como una forma de "renderización". Debe averiguar cómo manejar sus datos en términos de atributos, búferes uniformes y texturas.
Con los sombreadores de cómputo OpenGL 4.3 y OpenGL ES 3.1, las cosas se vuelven un poco más confusas. Un sombreador de cómputo puede acceder a la memoria a través de SSBO / Carga de imagen / Almacenar de manera similar a las operaciones de cálculo OpenCL (aunque OpenCL ofrece punteros reales, mientras que GLSL no lo hace). Su interoperabilidad con OpenGL también es mucho más rápida que OpenCL / GL interoperabilidad.
Aun así, los sombreadores de cómputo no cambian un hecho: las operaciones de cómputo OpenCL operan con una precisión muy diferente a la de los sombreadores de cómputo de OpenGL. Los requisitos de precisión de punto flotante de GLSL no son muy estrictos, y los de OpenGL ES son incluso menos estrictos. Entonces, si la precisión del punto flotante es importante para sus cálculos, OpenGL no será la forma más efectiva de calcular lo que necesita calcular.
Además, los sombreadores de cómputo OpenGL requieren hardware compatible con 4.x, mientras que OpenCL puede ejecutarse en hardware mucho más inferior.
Además, si está haciendo cálculos mediante la cooptación de la canalización de renderizado, los controladores OpenGL seguirán suponiendo que está haciendo renderizado. Por lo tanto, tomará decisiones de optimización basadas en esa suposición. Optimiza la asignación de los recursos del sombreador suponiendo que está dibujando una imagen.
Por ejemplo, si está renderizando en un framebuffer de punto flotante, el controlador puede decidir darle un buffer de frame R11_G11_B10, porque detecta que no está haciendo nada con el alfa y su algoritmo podría tolerar la menor precisión. Sin embargo, si usas load / store de imagen en lugar de framebuffer, es mucho menos probable que obtengas este efecto.
OpenCL no es una API de gráficos; es una API de computación
Además, OpenCL simplemente te da acceso a más cosas. Le da acceso a niveles de memoria que están implícitos con respecto a GL. Cierta memoria se puede compartir entre subprocesos, pero las instancias de sombreador separadas en GL no pueden afectarse directamente entre sí (fuera de Image Load / Store, pero OpenCL se ejecuta en hardware que no tiene acceso a eso).
OpenGL oculta lo que el hardware está haciendo detrás de una abstracción. OpenCL lo expone a casi exactamente lo que está pasando.
Puede usar OpenGL para hacer cálculos arbitrarios. Pero no quieres ; no mientras haya una alternativa perfectamente viable. Compute en OpenGL lives para dar servicio a la canalización de gráficos.
La única razón para elegir OpenGL para cualquier tipo de operación informática sin representación es admitir hardware que no puede ejecutar OpenCL. En la actualidad, esto incluye una gran cantidad de hardware móvil.
Además de las respuestas ya existentes, OpenCL / CUDA no solo se ajusta más al dominio computacional, sino que además no abstrae demasiado el hardware subyacente. De esta forma, puede obtener beneficios de cosas como la memoria compartida o el acceso a la memoria fusionada de forma más directa, que de lo contrario se incluiría en la implementación real del sombreador (que en sí mismo no es más que un kernel especial de OpenCL / CUDA, si lo desea).
Sin embargo, para sacar provecho de estas cosas, también debe ser un poco más consciente del hardware específico en el que se ejecutará su kernel, pero no intente tomar esas cosas en cuenta explícitamente usando un sombreador (incluso si es completamente posible).
Una vez que haga algo más complejo que las simples rutinas BLAS de nivel 1, seguramente apreciará la flexibilidad y la genérica de OpenCL / CUDA.
Algo que no se ha mencionado en ninguna respuesta hasta ahora ha sido la velocidad de ejecución. Si su algoritmo puede expresarse en gráficos OpenGL (p. Ej., Sin escrituras dispersas, sin memoria local, sin grupos de trabajo, etc.) muy a menudo se ejecutará más rápido que una contraparte OpenCL. Mi experiencia específica de esto ha sido hacer núcleos de filtro de imágenes (recopilar) en AMD, nVidia, IMG y Qualcomm GPU. Las implementaciones OpenGL invariablemente se ejecutan más rápido incluso después de la optimización hardcore del núcleo OpenCL. (a un lado: sospecho que esto se debe a años de hardware y controladores específicamente ajustados a cargas de trabajo orientadas a gráficos.)
Mi consejo sería que si su programa de cómputo parece que se correlaciona bien con el dominio de gráficos, entonces use OpenGL. Si no, OpenCL es más general y más simple para expresar problemas de cómputo.
Otro punto para mencionar (o preguntar) es si estás escribiendo como aficionado (es decir, para ti) o comercialmente (es decir, para distribuirlo a otros). Si bien OpenGL es compatible prácticamente en todas partes, OpenCL carece totalmente de soporte en dispositivos móviles y, en mi opinión, es poco probable que aparezca en Android o iOS en los próximos años. Si la compatibilidad de plataformas múltiples desde una única base de código es un objetivo, entonces OpenGL puede ser forzado sobre usted.
Aunque actualmente OpenGL sería la mejor opción para gráficos, esto no es permanente.
Podría ser práctico para OpenGL fusionarse eventualmente como una extensión de OpenCL. Las dos plataformas son aproximadamente 80% iguales, pero tienen diferentes caprichos de sintaxis, nomenclatura diferente para aproximadamente los mismos componentes del hardware. Eso significa dos idiomas para aprender, dos API para descubrir. Los desarrolladores de controladores gráficos preferirían una fusión porque ya no tendrían que desarrollarse para dos plataformas separadas. Eso deja más tiempo y recursos para la depuración del controlador. ;)
Otra cosa que debe tenerse en cuenta es que los orígenes de OpenGL y OpenCL son diferentes: OpenGL comenzó y ganó impulso durante los primeros días de la tubería fija sobre una red y se agregó y desaprobó lentamente a medida que evolucionó la tecnología. OpenCL, en cierto modo, es una evolución de OpenGL en el sentido de que OpenGL comenzó a utilizarse para el procesamiento numérico, ya que la flexibilidad (no planificada) de las GPU lo permitía. "Gráficos frente a computación" es realmente más un argumento semántico. En ambos casos, siempre intentas asignar tus operaciones matemáticas al hardware con el mayor rendimiento posible. Hay partes del hardware de la GPU que vanilla CL no usará pero que no mantendrán una extensión aparte de hacerlo.
Entonces, ¿cómo podría OpenGL trabajar bajo CL? Especulativamente, los rasterizadores triangulares podrían ponerse en cola como una tarea CL especial. Las funciones especiales de GLSL podrían implementarse en OpenCL de vanilla, y luego ser reemplazadas por instrucciones del controlador aceleradas por hardware durante la compilación del kernel. Escribir un sombreador en OpenCL, a la espera de que se hayan proporcionado las extensiones de la biblioteca, no parece una experiencia dolorosa.
Llamar a uno para que tenga más funciones que el otro no tiene mucho sentido ya que ambos obtienen el 80% de las mismas características, justo bajo una nomenclatura diferente. Afirmar que OpenCL no es bueno para los gráficos porque está diseñado para computación no tiene sentido porque el procesamiento de gráficos es computacional.
Bueno, desde OpenGL 4.5 estas son las características que OpenCL 2.0 tiene que OpenGL 4.5 no (por lo que pude ver) (esto no cubre las características que OpenGL tiene que OpenCL no tiene):
Eventos
Mejor Atomics
Bloques
Funciones de grupo de trabajo: work_group_all y work_group_any work_group_broadcast: work_group_reduce work_group_inclusive / exclusive_scan
Enqueue Kernel de Kernel
Punteros (aunque si está ejecutando en la GPU esto probablemente no importe)
Algunas funciones matemáticas que OpenGL no tiene (aunque podrías construirlas tú mismo en OpenGL)
Memoria virtual compartida
(Más) Opciones de compilación para Kernels
Fácil de seleccionar una GPU en particular (o de lo contrario)
Se puede ejecutar en la CPU cuando no hay GPU
Más soporte para esas plataformas de hardware de nicho (por ejemplo, FGPA)
En algunas (¿todas?) Plataformas, no necesita una ventana (y su enlace de contexto) para hacer cálculos.
OpenCL permite un poco más de control sobre la precisión de los cálculos (incluso algunos a través de esas opciones de compilación).
Muchos de los anteriores son principalmente para una mejor interacción CPU - GPU: Eventos, Memoria Virtual Compartida, Punteros (aunque estos podrían potencialmente beneficiar a otras cosas también).
OpenGL ha adquirido la capacidad de ordenar las cosas en diferentes áreas de la memoria del Cliente y del Servidor ya que muchas de las otras publicaciones se han realizado aquí. OpenGL tiene una mejor barrera de memoria y soporte atómico ahora y le permite asignar cosas a diferentes registros dentro de la GPU (aproximadamente en el mismo grado en que OpenCL puede). Por ejemplo, puede compartir registros en el grupo de cálculo local ahora en OpenGL (usando algo como las GPU AMD LDS (compartir datos locales) (aunque esta característica en particular solo funciona con los sombreadores de cómputo OpenGL en este momento). OpenGL tiene implementaciones más efectivas en algunas plataformas (como los controladores Open Source Linux). OpenGL tiene acceso a más hardware de función fija (como han dicho otras respuestas). Si bien es cierto que a veces se puede evitar el hardware de función fija (por ejemplo, Crytek utiliza una implementación de "software" buffer de profundidad) hardware de función fija puede administrar la memoria muy bien (y generalmente mucho mejor que alguien que no está trabajando para una compañía de hardware GPU) y es muy superior en la mayoría de los casos. Debo admitir que OpenCL tiene bastante buena textura de función fija soporte que es una de las principales áreas de funciones fijas de OpenGL.
Yo diría que Intels Knights Corner es una GPU x86 que se controla a sí misma. También argumentaría que OpenCL 2.0 con sus funciones de textura (que en realidad están en versiones menores de OpenCL) se puede usar para ofrecer el mismo grado de rendimiento que user2746401.
La "característica" que OpenCL está diseñada para el cálculo de propósito general, mientras que OpenGL es para gráficos. Puedes hacer cualquier cosa en GL (es Turing-completo) pero luego estás manejando un clavo usando el mango del destornillador como un martillo.
Además, OpenCL puede ejecutarse no solo en GPU, sino también en CPU y varios aceleradores dedicados.
OpenCL (en versión 2.0) describe un entorno computacional heterogéneo, donde cada componente del sistema puede producir y consumir tareas generadas por otros componentes del sistema. Ya no se necesitan más nociones de CPU, GPU (etc.): solo tiene Host y Dispositivo (s).
OpenGL, al contrario, tiene una división estricta de CPU, que es productora de tareas y GPU, que es consumidor de tareas. Eso no está mal, ya que una menor flexibilidad garantiza un mayor rendimiento. OpenGL es simplemente un instrumento de alcance más limitado.
OpenCL se crea específicamente para informática. Cuando haces computación científica usando OpenGL siempre tienes que pensar cómo mapear tu problema informático al contexto gráfico (es decir, hablar en términos de texturas y primitivas geométricas como triángulos, etc.) para que tu computación funcione.
En OpenCL, simplemente formule su cálculo con un kernel de cálculo en un búfer de memoria y estará listo. Esto es realmente una GRAN victoria (diciendo que desde una perspectiva de haber pensado e implementado ambas variantes).
Los patrones de acceso a la memoria son iguales (su cálculo aún está ocurriendo en una GPU, pero las GPU se vuelven cada vez más flexibles).
Pero, ¿qué otra cosa podría esperar que usar más de una docena de "CPUs" paralelas sin quejarse de cómo traducir, por ejemplo (ejemplo tonto) Fourier a Triángulos y Quads ...?
Otra razón importante es que OpenGL / GLSL solo es compatible con tarjetas gráficas. Aunque el uso de varios núcleos comenzó con el uso de hardware de gráficos, hay muchos proveedores de hardware que trabajan en plataformas de hardware multinúcleo para cómputo. Por ejemplo, vea Intels Knights Corner.
El desarrollo de código para el cálculo usando OpenGL / GLSL evitará que utilice cualquier hardware que no sea una tarjeta gráfica.
Una característica notable serían las escrituras dispersas, otra sería la ausencia de la "inteligencia de Windows 7". Windows 7, como probablemente sabrá, matará el controlador de pantalla si OpenGL no funciona durante 2 segundos más o menos (no me clave en la hora exacta, pero creo que son 2 segundos). Esto puede ser molesto si tienes una operación larga.
Además, OpenCL obviamente funciona con una variedad de hardware mucho mayor que solo la tarjeta gráfica, y no tiene una tubería rígida orientada a gráficos con "restricciones artificiales". Es más fácil (trivial) ejecutar varias secuencias de comandos concurrentes también.