Explicamos que son los NVIDIA CUDA Cores de las tarjetas gráficas y como funciona esta tecnología y como ha permitido dar un importante salto en la computación mediante la paralelización

Siempre que hablamos de las tarjetas gráficas de NVIDIA, hablamos de sus especificaciones técnicas, como pueda ser la frecuencia de trabajo de la GPU, la cantidad de memoria, el TDP o los CUDA Cores, entre otros. Conocemos de sobra que es la frecuencia y como actúa sobre el chip gráfico, que es el TDP o la cantidad de memoria y el tipo de la misma, así como otras consideraciones de las mismas, pero hoy nos vamos a centrar en hablar de NVIDIA CUDA, la tecnología en la que se basan los chips de silicio de NVIDIA.


¿QUÉ ES CUDA?




La arquitectura NVIDIA CUDA es en la que se basan las tarjetas gráficas de NVIDIA destinadas a realizar el cálculo en paralelo, ofreciendo una gran potencia de cálculo en la GPU, lo cual permite que el sistema tenga un gran rendimiento. NVIDIA hasta la fecha ha vendido millones de graficas que incluyen la solución NVIDIA CUDA, siendo muy valorada entre los desarrolladores, investigadores, científicos y también los gamers. El segmento que más aprovecha esta tecnología son los tres primeros, ya que NVIDIA CUDA permite mover sin problemas soluciones dentro de los campos del procesamiento de video e imagen, la biología o la química computacional, la simulación dinámica de fluidos, el análisis sismológicos u otras tantas aplicaciones que requieren de gran potencia de computo.


ARQUITECTURA NVIDIA CUDA


En la arquitectura clásica de una tarjeta gráfica podemos encontrar la presencia de dos tipos de procesadores, los procesadores de vértices y los procesadores de fragmentos, dedicados a tareas distintas e indispensables dentro del cauce gráfico y con repertorios de instrucciones diferentes. Esto presenta dos problemas importantes, por un lado el desequilibrio de carga que aparece entre ambos procesadores y por otro la diferencia entre sus respectivos repertorios de instrucciones. De este modo, la evolución natural en la arquitectura de una GPU ha sido la búsqueda de una arquitectura unificada donde no se distinguiera entre ambos tipos de procesadores. Asi se llegó a la arquitectura CUDA, donde todos los núcleos de ejecución necesitan el mismo repertorio de instrucciones y prácticamente los mismos recursos.

Podemos ver en la imagen la presencia de unas unidades de ejecución denominados Streaming Multiprocessors (SM), 8 unidades en el ejemplo de la figura, que están interconectadas entre sí por una zona de memoria común. Cada SM está compuesto a su vez por unos núcleos de computo llamados ‘núcleos CUDA’, que son los encargados de ejecutar las instrucciones y que en nuestro ejemplo vemos que hay 32 núcleos por cada SM, lo que hace un total de 256 núcleos de procesamiento. Este diseño de hardware permite la programación sencilla de los núcleos de la GPU utilizando un lenguaje de alto nivel como puede ser el lenguaje C para NVIDIA CUDA. De este modo, el programador simplemente escribe un programa secuencial dentro del cual se llama a lo que se conoce como kernel, que puede ser una simple función o un programa completo.

Este kernel se ejecuta de forma paralela dentro de la GPU como un conjunto hilos (threads y que el programador organiza dentro de una jerarquía en la que pueden agruparse en bloques (blocks), y que a su vez se pueden distribuir formando una malla (grid). Por conveniencia, los bloques y las mallas pueden tener una, dos o tres dimensiones. Existen multitud de situaciones en las que los datos con los que se trabaja poseen de forma natural una estructura de malla, pero en general, descomponer los datos en una jerarquía de hilos no es una tarea fácil. Asi pues, un bloque de hilos es un conjunto de hilos concurrentes que pueden cooperar entre ellos a través de mecanismos de sincronización y compartir accesos a un espacio de memoria exclusivo de cada bloque. Y una malla es un conjunto de bloques que pueden ser ejecutados independientemente y que por lo tanto pueden ser lanzados en paralelo en los Streaming Multiprocessors (SM).

Cuando se invoca un kernel, el programador especifica el número de hilos por bloque y el número de bloques que conforman la malla. Una vez en la GPU, a cada hilo se le asigna un único número de identificación dentro de su bloque, y cada bloque recibe un identificador dentro de la malla. Esto permite que cada hilo decida sobre qué datos tiene que trabajar, lo que simplifica enormemente el direccionamiento de memoria cuando se trabaja con datos multidimensionales, como es el caso del procesado de imágenes o la resolución de ecuaciones diferenciales en dos y tres dimensiones.

Otro aspecto a destacar en la arquitectura CUDA es la presencia de una unidad de distribución de trabajo que se encarga de distribuir los bloques entre los SM disponibles. Los hilos dentro de cada bloque se ejecutan concurrentemente y cuando un bloque termina, la unidad de distribución lanza nuevos bloques sobre los SM libres. Los SM mapean cada hilo sobre un núcleo SP, y cada hilo se ejecuta de manera independiente con su propio contador de programa y registros de estado. Dado que cada hilo tiene asignados sus propios registros, no existe penalización por los cambio de contexto, pero en cambio sí existe un límite en el número máximo de hilos activos debido a que cada SM tiene un número determinado de registros.

Una característica particular de la arquitectura CUDA es la agrupación de los hilos en grupos de 32. Un grupo de 32 hilos recibe el nombre de warp, y se puede considerar como la unidad de ejecución en paralelo, ya que todos los hilos de un mismo warp se ejecutan físicamente en paralelo y por lo tanto comienzan en la misma instrucción (aunque después son libres de bifurcarse y ejecutarse independientemente). Así, cuando se selecciona un bloque para su ejecución dentro de un SM, el bloque se divide en warps, se selecciona uno que esté listo para ejecutarse y se emite la siguiente instrucción a todos los hilos que forman el warp. Dado que todos ellos ejecutan la misma instrucción al unísono, la máxima eficiencia se consigue cuando todos los hilos coinciden en su ruta de ejecución (sin bifurcaciones). Aunque el programador puede ignorar este comportamiento, conviene tenerlo en cuenta si se pretende optimizar alguna aplicación.

En cuanto a la memoria, durante su ejecución los hilos pueden acceder a los datos desde diferentes espacios dentro de una jerarquía de memoria. Así, cada hilo tiene una zona privada de memoria local y cada bloque tiene una zona de memoria compartida visible por todos los hilos del mismo bloque, con un elevado ancho de banda y baja latencia (similar a una cache de nivel 1). Finalmente, todos los hilos tienen acceso a un mismo espacio de memoria global (del orden de MiB o GiB) ubicada en un chip externo de memoria DRAM. Dado que esta memoria posee una latencia muy elevada, es una buena práctica copiar los datos que van a ser accedidos frecuentemente a la zona de memoria compartida.

El modelo de programación CUDA asume que tanto el host como el device mantienen sus propios espacios separados de memoria. La única zona de memoria accesible desde el host es la memoria global. Además, tanto la reserva o liberación de memoria global como la transferencia de datos entre el host y el device debe hacerse de forma explícita desde el host mediante llamadas a funciones específicas de CUDA.


¿QUÉ ES LA ACELERACIÓN DE LA COMPUTACIÓN POR GPU?


El otro punto clave de los CUDA core es la aceleración del procesamiento grafico cuando se combina una GPU con el procesador (CPU), lo cual permite realizar aplicaciones a deep learning, análisis e ingeniería. Este sistema fue introducido por NVIDIA en el año 2017 y desde entonces, las GPU se han ido instalando en centros de datos altamente eficientes energéticamente en universidades, instalaciones gubernamentales, grandes empresas y PYMEs de todo el mundo. Estos tienen una gran importancia en la aceleración de aplicaciones que van desde la inteligencia artificial hasta los coches, drones y robots.


¿CÓMO FUNCIONA ESTA ACELERACIÓN EN UTILIDADES DE SOFTWARE?


Este sistema de aceleración del cálculo en tarjetas gráficas, hace que la mayor parte del peso de la carga de cómputo pase a la GPU, dejando que el código restante se ejecute en la CPU. La transferencia del peso de la computación es automática y el usuario no tiene que hacer nada, solamente, el usuario notara que las tareas paralizadas tendrán un funcionamiento más ágil.

Dicho sistema se explica de manera más sencilla, si entendemos las diferencias básicas entre un procesador y la tarjeta gráfica. Si vemos una CPU internamente. Las CPU se desarrollan con un número limitado de núcleos, por ejemplo, un Intel i7 7700K tiene cuatro núcleos, lo cual indica que son cuatro procesadores para la computación en serie, mientras que las GPU cuentan con miles de núcleos, más pequeños, pero mucho más eficientes, los cuales son desarrollados para ofrecer múltiples tareas simultaneas. Un claro ejemplo es la NVIDIA GTX 1080 Ti, la tarjeta gráfica destinada al gaming más potente del mercado, que nos ofrece 3594 CUDA Cores.

La diferencia entre ambos es muy importante, como podemos observar, ya que entre un procesador de 4 núcleos y la tarjeta gráfica con 3594 CUDA Cores, encontramos no solo una diferencia gigante de núcleos para la computación, sino una diferencia entre la computación en serie y el paralelo. La computación en serie quiere decir, de manera sencilla, que los núcleos harían una única tarea, mientras que los CUDA Cores son capaces, cada uno, de coger un trozo de la tarea global y trabajarla por su parte, luego uniendo todos los elementos y dando a la salida la tarea completada. Esto es lo que permite que una tarjeta gráfica sea mucho más eficiente y ofrezca una mayor potencia con respecto a un procesador en tareas que requieran mucho paralelismo.


PROCESAMIENTO EN PARALELO BAJO CUDA


Anteriormente los sistemas hacían taras de procesamiento centralizado en la CPU, que era quien realizaba todo el trabajo, pero ahora las tareas de procesamiento se reparten entre la CPU y la GPU. Este nuevo sistema de trabajo requiere novedades tecnológicas y buscar una nueva solución, por eso NVIDIA ha desarrollado CUDA, para la computación en paralelo, la cual afecta a las tarjetas gráficas GeForce, Quadro y Tesla, permitiendo a los desarrolladores, mejorar el rendimiento y agilizar las tareas.

Uno de los segmentos más beneficiados de NVIDIA CUDA ha sido la industria científica, quien ha visto como proyectos de topografía, mapeado, previsión de tormentas y otros, han visto como su día a día ha mejorado y se ha agilizado. Hoy en día miles de investigadores pueden hacer trabajo sobre dinámica molecular en un ámbito académico y farmacéutico, que agiliza el desarrollo y la investigación para la farmacología, permitiendo avanzar en menos tiempo en la cura de enfermedades complejas como pueda ser el cáncer, el Alzheimer y otras enfermedades hoy en día incurables.

No solamente en el segmento científico, muchas compañías también usan NVIDIA CUDA para realizar predicciones en operaciones financieras de riesgo, agilizando el tiempo en al menos dieciocho veces o más. Otros ejemplos es la gran acogida que tienen las GPU Tesla para el Cloud Computing y otros sistemas de computación que requieren de una gran potencia de trabajo. CUDA también permite a los vehículos autónomos operar de manera sencilla y eficiente, pudiendo hacer cálculos en tiempo real que no se podrían hacer mediante otros sistemas. Esta agilidad de computación permite al vehículo tomar importantes decisiones en muy poco tiempo, para esquivar obstáculos, moverse sin problemas o evitar accidentes.


PLATAFORMA DE CÁLCULO PARALELO CUDA


La gran ventaja de NVIDA CUDA es la paralelización de las tareas, permitiendo mediante extensiones, trabajar en C y C++, de manera paralela, mediante el procesamiento de tareas y datos con diferentes niveles de importancia. Estas tareas de paralelización se pueden realizar mediante varios lenguajes de alto nivel, como C y C++ y más reciente en Python, que es de bajo nivel o sencillamente mediante estándares abiertos que contengan directivas OpenACC.

CUDA actualmente es la plataforma más utilizada para la aceleración de tareas y se han logrado grandes avances gracias al desarrollo bajo esta tecnología. Tanto es asi que hoy en día, la tecnología CUDA es la más utilizada y una de las más importantes, tanto es así que en todas las universidades españolas se forma en este aspecto, enseñando programación en base NVIDIA CUDA, ya que será útil para el estudiante en un futuro, permitiendo la paralelización de las tareas y agilizando los procesos.


TE RECOMENDAMOS.

Compartir.

Sobre el Autor

Técnico Intermedio en PRL, Técnico Superior en Energías Renovables y en Desarrollo de Productos Electrónicos. Docente de Formación No Reglada. Exigente con el hardware y curioso por naturaleza. Kirchhoff, Maxwell y Thevenin mis maestros y mi pasatiempo el álgebra booleana. Igual te calculo el potencial eólico del viento para un panel fotovoltaico, que te calculo la generación solar de un aerogenerador… o algo así. Stargate es la mejor serie de la historia de la ciencia ficción y lo sabes.

  • Félix García

    Gran artículo, se agradece el trabajo.

  • alex

    y después hablara de los shaders de amd?

    • deltafrost91

      no se supone que son stream processors

      • alex

        SI ESO

  • FullKiller1—RGB—

    Muy buen articulo.