Este documento presenta conceptos básicos de programación paralela en GPU. Explica conceptos como paralelismo, distribución de datos, reducciones y condiciones de carrera. Luego, introduce herramientas para programar en GPU, incluyendo compilación de código CUDA a PTX y enlazado con librerías CUDA. Finalmente, provee ejemplos ilustrativos de diferentes estrategias de programación paralela en GPU.
1. Computación de Propósito General en
Unidades de Procesamiento Gráfico
(GPGPU)
E. Dufrechou, P. Ezzatti y M. Pedemonte
Dufrechou,
Clase 3 – Programación paralela GPGPU
Clases 3
Programación paralela
Clase 3 – Programación paralela GPGPU
Contenido
• Conceptos básicos de programación paralela
• Herramientas para GPU (básico)
– Compilación
– Hello world
Clase 3 – Programación paralela GPGPU
1
2. Conceptos básicos de
Programación Paralela
Clase 3 – Programación paralela GPGPU
Conceptos Básicos de Programación Paralela
• Múltiples unidades de cómputo trabajando en forma
coordinada
• Comunicación
• Sincronización
• División
• De tareas
• De datos
Clase 3 – Programación paralela GPGPU
Conceptos Básicos de Programación Paralela
• Paralelismo de
• Memoria compartida (multi-core)
• Memoria distribuida (cluster)
• Contexto
• Homogéneo
• Heterogéneo
• Balance de carga
Clase 3 – Programación paralela GPGPU
2
3. Conceptos Básicos de Programación Paralela
En este caso:
• Muchas unidades de cómputo trabajando en forma
coordinada.
• División de datos.
• Paralelismo “similar” a paralelismo a memoria compartida
(multi-core).
• Unidades de procesamiento homogéneas.
Clase 3 – Programación paralela GPGPU
Conceptos Básicos de Programación Paralela
En los ejemplos que se verán a continuación:
• Se utilizará una sintaxis inspirada en la de Matlab.
• El código escrito en color negro ejecuta en forma secuencial.
• El código escrito en color azul indica palabras reservadas que son
directivas para el manejo de paralelismo.
• El código escrito en color rojo indica el punto de ramificación del
paralelismo.
• El código escrito en color verde es el código que es ejecutado en forma
paralela por cada una de las unidades de procesamiento.
Clase 3 – Programación paralela GPGPU
Conceptos Básicos de Programación Paralela
Ejemplo 0:
• Se tiene una matriz con
4 columnas y se quiere
obtener la suma por
columnas de la matriz.
• Se dispone de una única
unidad de
procesamiento.
Clase 3 – Programación paralela GPGPU
3
4. Conceptos Básicos de Programación Paralela
Ejemplo 0:
Res = zeros(1,4)
[m,n] = size(Mat)
For j = 1:4
For i = 1 : m
Res(j) = Res(j) +
Mat(i,j)
Clase 3 – Programación paralela GPGPU
Conceptos Básicos de Programación Paralela
Ejemplo 1:
• Se tiene una matriz con
4 columnas y se quiere
obtener la suma por
columnas de la matriz.
• Se dispone de cuatro
unidades de
procesamiento.
Clase 3 – Programación paralela GPGPU
Conceptos Básicos de Programación Paralela
Ejemplo 1:
Res = zeros(1,4)
[m,n] = size(Mat)
begin_parallel(4)
For j = 1:4
For i = 1 : m
Res(j) = Res(j) + Mat(i,j)
end_parallel
Clase 3 – Programación paralela GPGPU
4
5. Conceptos Básicos de Programación Paralela
Ejemplo 2:
• Se tiene una matriz con 400 columnas y se quiere obtener la
suma por columnas de la matriz.
• Se dispone de cuatro unidades de procesamiento.
Clase 3 – Programación paralela GPGPU
Conceptos Básicos de Programación Paralela
Ejemplo 2:
Res = zeros(1,400)
[m,n] = size(Mat)
begin_parallel(4)
For j = 1:400
For i = 1 : m
Res(j) = Res(j) + Mat(i,j)
end_parallel
Clase 3 – Programación paralela GPGPU
Conceptos Básicos de Programación Paralela
Ejemplo 3:
• Se tiene una matriz con 400 columnas y se quiere obtener la
suma por columnas de la matriz.
• Se sabe que el trabajo para realizar la suma de una columna es
irregular (por ejemplo, sumar 0 es menos costoso
computacionalmente que sumar otro número).
• Se dispone de cuatro unidades de procesamiento.
Clase 3 – Programación paralela GPGPU
5
6. Conceptos Básicos de Programación Paralela
Distribución de datos
Distribución por bloque Distribución cíclica
Clase 3 – Programación paralela GPGPU
Conceptos Básicos de Programación Paralela
Ejemplo 3:
• Es posible achicar el tamaño de los bloques.
• Por ejemplo: de 100 columnas pasar a 10 columnas por bloque.
Res = zeros(1,400)
[m,n] = size(Mat)
begin_parallel(40)
For j = 1:400
For i = 1 : m
Res(j) = Res(j) + Mat(i,j)
end_parallel
Clase 3 – Programación paralela GPGPU
Conceptos Básicos de Programación Paralela
Ejemplo 4:
• Se tiene una matriz con 400 columnas y se quiere obtener la
suma por columnas de la matriz.
• Se sabe que el trabajo para realizar la suma de una columna es
irregular (por ejemplo, sumar 0 es menos costoso
computacionalmente que sumar otro número).
• Se dispone de cuatro unidades de procesamiento.
• En este caso, además se quiere obtener la suma parcial por
unidad de procesamiento.
Clase 3 – Programación paralela GPGPU
6
7. Conceptos Básicos de Programación Paralela
Ejemplo 4:
Clase 3 – Programación paralela GPGPU
Conceptos Básicos de Programación Paralela
Ejemplo 4:
Res = zeros(1,400)
Res2 = zeros(1,4)
[m,n] = size(Mat)
begin_parallel(40)
For j = 1:400
private idP = myId()
For i = 1 : m
Res(j) = Res(j) + Mat(i,j)
Res2(idP) = Res2(idP) + Res(j)
end_parallel
Clase 3 – Programación paralela GPGPU
Conceptos Básicos de Programación Paralela
Ejemplo 5:
• Se tiene una matriz con 400 columnas y se quiere obtener la
suma de todos los elementos de la matriz.
• Se dispone de cuatro unidades de procesamiento.
Clase 3 – Programación paralela GPGPU
7
8. Conceptos Básicos de Programación Paralela
Solución 1
• Se suma por columna
• Luego se suma todo el vector intermedio
Clase 3 – Programación paralela GPGPU
Conceptos Básicos de Programación Paralela
Solución 1
• Se suma por columna y luego se suma el vector intermedio.
Res = zeros(1,400)
[m,n] = size(Mat)
begin_parallel(4)
For j = 1:400
For i = 1 : m
Res(j) = Res(j) + Mat(i,j)
end_parallel
For j = 1:400
Sum = Sum + Res(j)
Clase 3 – Programación paralela GPGPU
Conceptos Básicos de Programación Paralela
Solución 2
• Se suma por columnas para cada unidad de procesamiento.
• Luego se suma el vector intermedio.
Clase 3 – Programación paralela GPGPU
8
9. Conceptos Básicos de Programación Paralela
Solución 2
Res = zeros(1,4)
• Se suma por columnas [m,n] = size(Mat)
para cada unidad de begin_parallel(4)
procesamiento y luego For j = 1:400
se suma el vector private idP = myId ()
intermedio. For i = 1 : m
Res(idP) = Res(idP) +
Mat(i,j)
end_parallel
For j = 1:4
Sum = Sum + Res(j)
Clase 3 – Programación paralela GPGPU
Conceptos Básicos de Programación Paralela
Solución 3
Res = zeros(1,4)
• Sumo por columna [m,n] = size(Mat)
y actualizo el begin_parallel(4)
resultado. For j = 1:400
private idP = myId ()
For i = 1 : m
• Concepto de
Res(idP) = Res(idP) + Mat(i,j)
reduce
end_parallel
begin_parallel(2)
For j = 1:4
Sum = Sum + Res(j)
end_parallel
Clase 3 – Programación paralela GPGPU
Conceptos Básicos de Programación Paralela
Race condition:
Res = zeros(1,4)
- Los hilos compiten por
[m,n] = size(Mat)
el acceso a los
begin_parallel(4)
registros.
For j = 1:400
- Pueden haber distintos
private idP = myId ()
ordenes de ejecución.
For i = 1 : m
Res(idP) = Res(idP) +Mat(i,j) - Distinto orden de
end_parallel
ejecución produce
resultados
begin_parallel(2)
diferentes!!!
For j = 1:4
Sum = Sum + Res(j)
- Este problema también
aparece en circuitos
end_parallel
electrónicos, base de
datos, etc.
Clase 3 – Programación paralela GPGPU
9
10. Conceptos Básicos de Programación Paralela
Reduce:
[m,n] = size(Mat)
- Generalmente están
begin_parallel(4) disponibles diversas
private Res operaciones:
For j = 1:400
• +
%private idP = myId ()
• *
For i = 1 : m
Res = Res + Mat(i,j) • min
end_parallel (reduce(+,Res)) • max
Clase 3 – Programación paralela GPGPU
Conceptos Básicos de Programación Paralela
Consideremos el
siguiente código: Res = zeros(1,11)
aux = 11
• Hay problemas por el begin_parallel(400)
acceso concurrente a For j = 1:400
la variable aux. private idP = myId ()
if (aux == 1)
aux = aux + 10
else
aux = aux - 1
end
Res(aux) = Res(aux) +Mat(j)
end_parallel
Clase 3 – Programación paralela GPGPU
Conceptos Básicos de Programación Paralela
Diferentes formas de
resolverlo: Res = zeros(1,11)
aux = 11
• Semáforos begin_parallel(400)
• Zonas mutuo For j = 1:400
excluidas private idP = myId ()
• Operaciones atómicas if (aux == 1)
aux = aux + 10
else
aux = aux - 1
end
Res(aux) = Res(aux) +Mat(i,j)
end_parallel
Clase 3 – Programación paralela GPGPU
10
11. Conceptos Básicos de Programación Paralela
Res = zeros(1,11)
Con zonas mutuo
begin_parallel(400)
excluidas
For j = 1:400
begin_mutex()
Solo un “hilo de if (aux == 1)
ejecución” entra en la aux = aux + 10
zona. else
aux = aux - 1
end
Res(aux) = Res(aux) +Mat(aux,j)
end_mutex()
end_parallel
Clase 3 – Programación paralela GPGPU
Conceptos Básicos de Programación Paralela
Res = zeros(1,11)
begin_parallel(400)
Con zonas mutuo private aux2
excluidas y For j = 1:400
operaciones atómicas begin_mutex()
if (aux == 1)
aux = aux + 10
else
aux = aux - 1
end
aux2=aux
end_mutex()
begin_atomic()
Res(aux2) = Res(aux2) +Mat(aux2,j)
end_atomic()
end_parallel
Clase 3 – Programación paralela GPGPU
Conceptos Básicos de Programación Paralela
Diferentes caminos dependiendo del thread (similar a zonas
mutuo excluidas)
begin_parallel(400)
For j = 1:400
private idP = myId ()
if (mod(idP,2) == 0)
Mat(j) = Mat(j) + 4
else
Mat(j) = Mat(j) + 2
end
end_parallel
• Estrategia comúnmente utilizada para implementar el
modelo de paralelismo Maestro-Esclavo: if soyMaestro()
Clase 3 – Programación paralela GPGPU
11
12. Conceptos Básicos de Programación Paralela
Conceptos vistos
• Paralelismo
• Estrategias de scheduling y balance de carga
• Distribución de datos
• Utilizar información del thread
• Reducciones
• Race conditions
• Operaciones atómicas
Clase 3 – Programación paralela GPGPU
Conceptos Básicos de Programación Paralela
Es conveniente tener en cuenta:
• La importancia del scheduling, distribución de datos y
control de sincronizaciones para un buen desempeño.
• Si bien parece obvio, además de buen desempeño es
necesario correctitud. Sin embargo, esto es más
complejo de comprobar que en programas secuenciales.
Clase 3 – Programación paralela GPGPU
Herramientas para GPU
Clase 3 – Programación paralela GPGPU
12
13. Compilación
C/C++ CUDA
Application
NVCC CPU Code
PTX Code
PTX to Target
Compiler
G80 … GPU
Target code
Clase 3 – Programación paralela GPGPU
Compilación
Compilación:
nvcc algo.cu –o algo
nvcc –c algo.cu
Salidas:
• Código C code (código del host)
• Se compila con una herramienta tradicional
(automáticamente).
• Código PTX
• Directamente código objeto.
• Para interpretar en tiempo de ejecución.
Clase 3 – Programación paralela GPGPU
Compilación
Enlazado
Los códigos CUDA requieren dos librerias dinámicas:
• The CUDA runtime library (cudart)
#include <cuda_runtime_api.h>
• The CUDA core library (cuda)
#include <cuda.h>
Clase 3 – Programación paralela GPGPU
13