Compute Unified Device Architecture (CUDA) Que es CUDA? Por qué CUDA? Dónde se usa CUDA? El Modelo CUDA Escalabilidad Modelo de programación Programación Heterogenea Memoria Compartida Alejandro Molina Zarca alejandro.molina2@um.es
Qué es CUDA? CUDA es una arquitectura de cálculo paralelo que hace referencia tanto a un compilador como a un conjunto de herramientas de desarrollo creadas por NVIDIA. Permite a los programadores usar una variación de C/C++ para codificar algoritmos en una GPU de NVIDIA. Mediante wrappers se puede utilizar Python, Fortran, Java, OpenGL y Direct3D.
Por qué CUDA? Hoy en día, el mercado demanda aplicaciones en tiempo real, alta definición y 3D que obtienen un alto rendimiento únicamente mediante el paralelismo. CUDA intenta explotar las ventajas de las GPU frente a las CPU de propósito general utilizando el paralelismo que ofrecen sus múltiples nucleos. En aplicaciones que utilicen numerosos hilos que relicen tareas independientes (que es lo que hacen las GPU al procesar gráficos de manera natural), una GPU podrá ofrecer un gran rendimiento.
Por qué CUDA?
Por qué CUDA?
Donde se usa CUDA? En prácticamente todas las aplicaciones de video actuales. AMBER, simulador de dinámica molecular. Numerix y CompatibL en el mercado financiero. En la actualidad existen más de 700 clusters de GPUs instalados en compañias Fortune 500 de todo el mundo, lo que incluye empresas como Schlumberger y Chevron en el sector energético o BNP Pariba en el sector bancario.
El Modelo CUDA CUDA intenta aprovechar el gran paralelismo, y el alto ancho de banda de la memoria en las GPU en aplicaciones con un gran coste aritmético frente a realizar numerosos accesos a memoria principal.
Escalabilidad El objetivo es que se desarrolle software con paralelismo escalable que aproveche el número de nucleos disponibles de forma transparente. Un programa multitarea se particiona automáticamente en bloques de hilos independientes, acorde al número de nucleos disponibles.
Escalabilidad Los mismos bloques, se dividen de forma óptima según el número de nucleos del sistema.
Modelo de programación CUDA extiende C, permitiendo al programador definir funciones denominadas kernel que son ejecutadas por N hilos diferentes en paralelo. Un kernel es ejecutado por uno o más bloques de hilos. Hay un límite de hilos por bloque que depende de los recursos del sistema. Actualmente es de 1024. Un hilo tiene un identificador único, accesible dentro del kernel mediante la variable threadidx.
Modelo de programación: - Kernel Mediante la sentencia global definimos el kernel Identificador de hilo Un bloque de N hilos Llamada al Kernel
Modelo de programacion Para mayor comodidad del programador, la variable threadidx es un vector de tres componentes gracias a la cual los hilos pueden ser identificados por su indice en una, dos y tres dimensiones. Los bloques de hilos también poseen una variable blockidx con el mismo propósito. La dimensión de un bloque es accesible mediante la variable blockdim.
Modelo de programación Las compoenentes x e y indican la posicion dentro del bloque en caso del thread, o del grid en caso del bloque.
Modelo de programación La cantidad de hilos por bloque y la cantidad de bloques pueden establecerse utilizando: Int dim3 Los hilos de un mismo bloque pueden coordinarse mediante la sentencia syncthreads().
Jerarquía de memoria Cada hilo posee una memoria local privada. Cada bloque de hilos tiene una memoria compartida visible a todos los hilos del bloque. Todos los hilos tienen acceso a la memoria global del sistema.
Jerarquía de memoria
Programación Heterogenea El modelo de programación de CUDA asume que los bloques que ejecutan los kernel se ejecutarán en la GPU mientras que el resto se ejecutará en la CPU. Tanto la GPU como la CPU mantienen su propio espacio de memoria DRAM, con lo que en tiempo de ejecución se deben gestionar las transferencias entre los dos espacios de memoria.
Programación Heterogenea
Memoria Compartida CUDA recomienda en la medida de lo posible, trabajar con memoria compartida, evitando así la sobrecarga sobre los accesos a memoria global. En el ejemplo de la multiplicación de matrices, sin memoria compartida, cada hilo leería una fila y columna de las matrices y calcularía el elemento de la matriz resultante. Partiendo la matriz en bloques, podemos mantener ocupado un bloque de hilos utilizando la memoria compartida.
Memoria Compartida
Memoria Compartida La sentencia device permite construir una submatriz, asi como obtener y establecer elementos a partir de una matriz.