Actualizado a: 22 de enero de 2024
Seguramente que has escuchado hablar alguna vez de GPGPU, es decir, de cómo usar la GPU para propósito general, al igual que hace la CPU. Esto tiene sus ventajas e inconvenientes, como vamos a ver en este artículo, además de aprender todo sobre este tipo de computación, aplicaciones, ejemplos, etc.
Quizás también te interese conocer:
¿Qué es la computación homogénea?
La computación homogénea, es la computación que se ha venido dando desde los inicios de la informática, es decir, donde la CPU era la encargada del procesamiento general, dejando a otros chips tareas específicas. Sin embargo, actualmente ha surgido el término computación heterogénea, que rompe con esta falta de versatilidad y flexibilidad a la hora de procesar como verás en el apartado siguiente.
¿Qué es la computación heterogénea?
La computación heterogénea es cada vez más importante. Comenzando por los centros de datos y HPC, que son los primeros en beneficiarse de ella, hasta actualmente otros muchos productos de consumo que también se han unido a los beneficios de esta solución donde no solo la CPU se usa para propósito general, también se pueden usar otros tipos de procesadores, o también puede haber mezclas de arquitecturas para obtener mayor eficiencia.
Ahora contamos con multitud de diferentes tipos de unidades de procesamiento: CPU, la GPU, DPU, VPU, DSP, FGPA como aceleradores dedicados, ASICs, NPUs, etc. Todas ellas con sus ventajas y desventajas. Por tanto, usar siempre la CPU para todo no es lo mejor, ya que se podrían usar otras de esas unidades para conseguir acelerar los procesos y conseguir consumos de energía más reducidos.
Por eso, en la computación heterogénea lo que se hace es asignar las diferentes cargas de trabajo a aquellas unidades de procesamiento que resultan tener el mayor rendimiento para esa carga específica y que consiguen la mejor eficiencia energética durante el proceso. Por ejemplo, la GPU, debido a su nivel de paralelismo, podría generar muchos más FLOPS que una CPU, por tanto, para ciertos cálculos de coma flotante, sería mucho mejor usar la GPU que la CPU, aunque no sea una carga de trabajo gráfica.
Como he dicho, esto se ha venido explotando especialmente en el sector de la supercomputación o HPC. Muchas de estas grandes máquinas usan aceleradores por GPU para muchas tareas, en vez de encargarle ese trabajo a la CPU que sería más lenta. Pero esto también ha contagiado a los chips destinados para dispositivos móviles y ordenadores personales. Más adelante veremos algunos ejemplos de esto…
Bajo este mismo punto de vista, algunos diseñadores de procesadores también están aplicando la heterogeneidad incluso dentro de los propios núcleos de la CPU, mezclando ISAs con diferencias o microarquitecturas distintas. Esto también lo veremos en el siguiente apartado.
Es algo que los expertos de la industria han estado buscando desde hace tiempo, y que no fue hasta hace unos años cuando comenzó a explotarse. Entre otros motivos, porque suponía adaptar el software a este paradigma, y eso implica tareas de desarrollo, compilación, etc.
Ejemplos de implementaciones de arquitecturas heterogéneas
Aquí tienes algunos ejemplos de arquitecturas heterogéneas en algunos productos bien conocidos:
- APU de AMD es un ejemplo magnífico de ello, ya que integra en el mismo chip monolítico una GPU y una CPU, compartiendo memoria unificada para ambos tipos de procesadores.
- Arm también creó su arquitectura heterogénea denominada big.LITTLE, donde mezcla núcleos de CPU Arm Cortex A-Series de menor rendimiento y con tamaños más compactos, así como más eficientes, con otros núcleos Cortex A-Series más grandes, potentes y de mayor consumo. De esa manera, se puede enviar la carga de trabajo, según su peso, a unas u otras para mejorar la eficiencia. Esto es lo que se conoce como multinúcleo heterogéneo.
- Intel comenzó hace algunas generaciones a hacer algo parecido en el ámbito de los x86. Ahora integra sus P-Core y E-Core, es decir, núcleos Performance y núcleos Efficient. Los primeros con una ISA más completa en cuanto a extensiones vectoriales, más grandes en cuanto a tamaño del silicio, con mayor rendimiento, pero también con mayor consumo. Los segundos son núcleos con una ISA algo cortada en cuanto a extensiones, por ejemplo, sin soporte para AVX-512, pero a cambio son más pequeños, y con un menor consumo. Así las cargas de trabajo más pesadas se les encargan a los P-Cores y las cargas de trabajo más livianas a los E-Cores.
- SoCs como los de Apple, Qualcomm, Mediatek, Samsung, SiFive, etc., que integran en el mismo chip unidades de procesamiento heterogéneas como puede ser una CPU, GPU, NPU, DSP, DSA, etc., e incluso dentro de la propia CPU también existe heterogeneidad en estos casos. Por ejemplo, Apple tiene sus núcleos de CPU Firestorm para alto rendimiento y sus núcleos de CPU Icestorm para eficiencia. Además, usa su Neural Engine (es una NPU) para acelerar cargas de trabajo de IA.
- En HPC o supercomputación, con el uso de GPGPUs y otras arquitecturas heterogéneas para conseguir las mayores tasas de FLOPS/w.
¿Qué es GPGPU?
GPGPU (General-Purpose Graphics Processing Unit) significa unidad de procesamiento gráfico de propósito general, y es un término que se refiere a una metodología de computación heterogénea moderna donde se usa la GPU para ayudar a la CPU con algunas cargas de trabajo, sin importar que estas cargas no sean tareas gráficas para las que fueron diseñadas estas GPUs.
Ten en cuenta que una GPU está diseñada para mejorar el paralelismo con cálculos de coma flotante, y eso permite a una GPU conseguir mayor rendimiento a la hora de realizar estos cálculos en comparación con una CPU. Pero para que eso sea posible, se necesita adaptar el software para ello, y eso pasa por usar una API diferente a las APIs gráficas (DirectX, OpenGL, Vulkan,…).
En el caso del hardware, no hay que modificar absolutamente nada. Todas las GPUs modernas son GPGPUs, tan solo hay que aprovechar sus procesadores programables para realizar cálculos de forma paralela y masiva en vez de que lo tenga que hacer la CPU de forma más lenta.
Como he dicho, las GPUs no se diseñaron para eso, pero para que puedan hacerlo es necesario usar estas APIs especiales de las que hablo, y con pequeños cambios en el código fuente del software, se puede aprovechar su potencial.
GPU vs CPU: diferencias clave
Si te preguntas cómo puede ser que una GPU que se diseñó para gráficos pueda procesar datos de forma más rápida y eficiente que una CPU, que fue diseñada especialmente para esto, la respuesta está en esta tabla:
CPU | GPU |
---|---|
Diseñada para procesamiento de propósito general, es decir, para ejecutar las instrucciones que componen los programas. | Componente especializado, diseñada para procesamiento gráfico. |
Recuento de núcleos bajo, con entre 2-64 (la mayoría de las CPUs actuales.) | Recuento de núcleos alto, con cientos o miles de unidades de procesamiento (en la mayoría de GPUs actuales). |
Mejor a la hora de ejecutar procesos en serie | Mejor para ejecuta procesos en paralelo |
Mejor para procesar una sola tarea compleja a la vez. | Mejor para procesar de varias tareas más simples a la vez. |
Por tanto, se podría pensar que es posible separar esas tareas complejas en otras más simples y que se encargue de ello la GPU. Esta es la idea, pero para ello se necesita modificar el código fuente del software y para ello se hace uso de las siguientes APIs…
APIs para GPGPU
Para poder aprovechar el potencial de la GPU para propósito general, en vez de encomendar esa carga a la CPU, se necesita modificar el código fuente del software haciendo uso de APIs que ayudan a los desarrolladores con ello. Estas APIs son:
NVIDIA CUDA
CUDA es la plataforma de cómputo paralelo y modelo de programación creado por NVIDIA, y especialmente diseñado para las GPUs de esta marca, ya que no funciona en otras. Todo está optimizado para los núcleos CUDA de las GeForce en este SDK.
Con esta API, los desarrolladores pueden acelerar la ejecución de ciertas tareas de cálculo usando la GPU como una GPGPU. Por ejemplo, aquí tienes un ejemplo de la web oficial de NVIDIA:
CUDA funciona tanto con lenguaje C como con C++ y Fortran de forma oficial, con la API que provee la propia NVIDIA. Sin embargo, terceros han creado complementos para poder usar otros lenguajes de programación diferentes como: Python, Perl, Java, Ruby, Lua, Common Lisp, Haskell, R, MATLAB, IDL, Julia, etc.
OpenCL
A diferencia de CUDA, OpenCL, de Khronos Group, es una API genérica. Inicialmente fue creada por Apple, y ahora puede ser usada para GPGPUs de cualquier marca, como AMD Radeon, Intel Arc, Imagination PowerVR, Qualcomm Adreno, Apple, Arm Mali, etc., así como también funciona en las gráficas NVIDIA GeForce.
Es más, incluso puede funcionar con unidades de procesamiento implementadas en FPGAs, DSPs y otros aceleradores o procesadores. Por tanto, es un proyecto más genérico, además de ser de código abierto, lo que abre muchas posibilidades.
Además, otra ventaja respecto a CUDA es que funciona en más plataformas. Mientras que CUDA solo corre bajo Windows y Linux, en el caso de OpenCL se puede instalar en sistemas operativos como Windows, Linux, FreeBSD, macOS y Android.
OpenCL (Open Computing Language) es un proyecto de bajo nivel para la computación heterogénea que usa GPGPU para el procesamiento. Con ella los desarrolladores pueden usar los núcleos de cómputo de la GPU para propósito general escribiendo en lenguaje de programación C/C++, de forma similar al ejemplo anterior con CUDA. Además, terceros también han desarrollado envoltorios o wrappers como los de CUDA para poder usar también lenguajes como Python, Java, R, GO, JavaScript y muchos otros.
OpenACC
Por último, no hay que olvidar otra API de este estilo. Es OpenACC, un estándar de programación paralela basado en directivas y dirigido a usuarios, diseñado para científicos e ingenieros interesados en portar sus códigos a una amplia variedad de plataformas heterogéneas de hardware de computación de alto rendimiento (HPC).
OpenACC pretende simplificar la programación paralela de plataformas y arquitecturas hardware heterogéneas de CPU/GPU con un esfuerzo de programación significativamente menor que el requerido con un modelo de bajo nivel. Es compatible con los lenguajes de programación C/C++ y Fortran, igual que CUDA.
Puede trabajar en AMD, Intel y NVIDIA, y fue desarrollado por Cray, CAPS Enterprise, The Portland Group, y NVIDIA. Y es cross-platform, o multiplataforma, por lo que funciona en diversos sistemas operativos como macOS, Linux, etc.