La computación científica sufrió una mejora con el uso de las GPUs y de APIs como OpenCL. Precisamente sobre lo que es esta API os vamos a hablar en este artículo, para que conozcáis las diferencias con otras APIs «gráficas», en que ámbitos se utiliza dicha API y cuál es su situación en la actualidad.
En primer lugar hemos de aclarar que OpenCL no es un tipo de hardware, sino un software o más bien una API que sirve para comunicar las aplicaciones con la GPU haciendo uso para ello de una abstracción a nivel de software de la propia GPU. Su diferencia con el resto de APIs que comunican las aplicaciones con la GPU es que no es lo que se puede decir una API gráfica, sino una API para la computación científica.
GPUs para computación
¿Qué es la computación en una GPU? Hay que tener en cuenta que las GPUs pueden ejecutar programas llamados shaders, los cuales se utilizan para manipular las características de las diferentes primitivas en el pipeline 3D, tengan la forma que tenga. Obviamente cualquier procesador solo ve una serie de datos en binario, por lo que cuando una unidad shader ejecuta un programa shader lo que hace es procesar un conjunto de datos y por tanto se puede utilizar para procesar cualquier tipo de datos.
A mediados de los 2000 con la llegada de las GPUs con shaders unificados apareció la posibilidad de utilizarlas en mercados más allá que el del gaming para PC, siendo el principal el de la computación científica, lo que permitió la salida de la gama NVIDIA Tesla a partir de 2007.
La diferencia de estas GPUs con las que se utilizan para gaming es su capacidad para trabajar con coma flotante de doble precisión, la cual no es necesaria en juegos, pero si en el mundo de la ciencia en todos sus aspectos. Ya sea para cálculos astronómicos o para producir un fármaco de siguiente generación.
OpenCL, una API para computación en GPU
Hasta la aparición de OpenCL las APIs gráficas estaban diseñadas solo para el renderizado de los gráficos, pero no de cara a la computación, por lo que no eran del todo eficientes para ejecutar algoritmos no-gráficos en una GPU. ¿La solución? Obvio, el desarrollo de una API para la computación, a la que llamaron OpenCL donde CL viene de Compute Library.
Pero, ¿en que se diferencian OpenCL y otras APIs? Podemos ejecutar OpenCL en cualquier tipo de procesador, no solo en GPUs, sino que si queremos podemos ejecutar código OpenCL es una CPU si nos es necesario, aparte que lo podemos ejecutar también en DSPs, FPGA, redes neurales y un largo etcétera.
El motivo de ello es que su modelo se basa en la computación distribuida donde tenemos una unidad Host que es la CPU y una serie de unidades de procesamiento que pueden ser GPUs, DSP, FPGA, etc. A las que se les van enviando las tareas a ejecutar. Siendo cada tarea un elemento de procesamiento, el cual cuando es procesada se le envía el resultado al host y/o una confirmación de que ha realizado dicha tarea. Cada elemento de procesamiento es un programa aparte, por tanto un hilo de ejecución con su propio contador de programa.
OpenCL no es una API gráfica
Hay que aclarar que OpenCL no controla el pipeline gráfico y por tanto no sirve para ejecutar gráficos, ya que una buena parte de las funciones que tiene OpenGL y otras APIs como Direct3D, Vulkan, etc. No se encuentran en OpenCL. Es más, originalmente se diseñé OpenCL para interactuar junto a OpenGL de manera conjunta y actualmente está diseñado para trabajar con Vulkan, la actual API gráfica del grupo Khronos.
Otra diferencia tiene que ver con el lenguaje de programación utilizado para ejecutar los programas Shader. En el caso de las APIs gráficas se hace uso de lenguajes shader de alto nivel, como es el caso de GLSL en el caso de OpenGL y Vulkan, HLSL en el caso de DirectX, etcétera.
En cambio con OpenCL no es así, se utilizan lenguajes de propósito general y no específico como pueden ser C y C++, lo que permite portar programas y algoritmos escritos en estos lenguajes a OpenCL para que sean ejecutados en todo tipo de dispositivos que soporten esta API y poder aprovechar su mayor versatilidad que los limitados lenguajes para shaders.
¿Cómo se aplica OpenCL en las aplicaciones del día a día?
OpenCL es ampliamente utilizado en algunas aplicaciones de PC, en especial las de carácter multimedia. Cuando por ejemplo en Photoshop le decimos al programa que ejecute un filtro de imagen a día de hoy se hace a través de OpenCL y el algoritmo se ejecuta en el hardware más adecuado y que soporte la API, por lo que si tenemos el componente más adecuado entonces la parte OpenCL se ejecutará en el mismo.
Otro tipo de aplicaciones cotidianas que utilizan OpenCL son los códecs de vídeo como por ejemplo AV1, HEVC, H.264, etcétera. La mayoría de ellos están programados en OpenCL por los mismos motivos que hemos comentado antes. Permite que la CPU los ejecute y los desarrolladores no tienen que romperse los cuernos si existe un códec de vídeo en el hardware y optimizar para el mismo.
Curiosamente OpenCL es además el motivo por el cual la parte 2D basada en VGA ha desaparecido de las tarjetas gráficas, y es que aunque parezca contradictorio es mucho mejor ejecutar a través de computación vía GPU la interfaz gráfica 2D de un sistema operativo.
Computación en DirectX y el boicot de NVIDIA con CUDA
OpenCL está en retroceso en cuanto a su uso, en especial después de que DirectX 11 incluyese los Compute Shaders en su repertorio y Apple también con su API Metal. La aparición de APIs gráficas con soporta parcial para la computación fue lo que hizo que OpenCL empezará a perder importancia.
Fue a partir de la introducción de los Compute Shaders que el abandono a OpenCL empezó a ser paulatino. La última versión utilizada de manera masiva es la 1.2 del estándar. Se trata de una versión muy rudimentaria en comparación con lo que pueden hacer otras APIs, ya que no soporta cosas como memoria virtual compartida, SPIR-V para una mejor interacción con Vulkan.
Pero es CUDA el principal enemigo de OpenCL. El motivo es que NVIDIA ha dominado durante años el mundo de las GPUs para alto rendimiento y eso lo han aprovechado para hacer que buena parte de la computación científica funcione alrededor de CUDA y no bajo OpenCL, ya que esto ata los programas a su hardware. NVIDIA ha podido hacer esto por una falta total de competencia hacía sus NVIDIA Tesla,
¿La forma de hacer boicot a OpenCL por parte de NVIDIA? No dando soporte de manera oficial a las mejoras en OpenCL 2.0, las cuales se encontraban también en CUDA. No solo eso, sino que NVIDIA nunca ha dado soporte a OpenCL en sus GPU NVIDIA Tesla, ni Quadro ni GeForce.
¿A la tercera va la vencida?
Al final con tal de evitar el descalabro final de OpenCL para su tercera versión han tenido que replantear toda la API en su tercera versión. En la versión buena parte de los elementos que formaron parte de la rama principal de OpenCL 2.x han sido degradadas a extensiones opcionales y por tanto el hardware base no necesita soportarlas de nuevo. Por lo que ahora es posible ejecutar OpenCL 3.0 en un hardware que tenga drivers para OpenCL 1.2 y añadir nosotros mismos las extensiones que queramos utilizar, una forma de hacer bypass a la censura de NVIDIA.
En todo el problema con el que se enfrenta OpenCL es que fuera del mundo de la computación científica donde más se utiliza es en los videojuegos. En especial a la hora de calcular las físicas de los videojuegos, así como la detección de colisiones. El hecho de que existan los Compute Shaders tanto en Vulkan como DirectX relegan el uso de OpenCL a la computación científica, la cual se encuentra en estos momentos con el dominio absoluto de CUDA.
Un mercado al que la API podría haber llegado y tener éxito es el de los dispositivos embebidos tipo Raspberry Pi, pero la versión 2.0 los dejo de lado, ya que se enfocó demasiado en la computación científica. La versión 3.0 no está pensada para llevar a OpenCL a sistemas embebidos que lo adoptarían sin problemas para multitud de aplicaciones, sino que busca ganar una guerra de antemano ya perdida y que dentro del propio grupo Khronos ya existe la competencia a OpenCL en forma de Vulkan.