computación de altas prestaciones con gpus
DESCRIPTION
Presente y futuro de los sistemas de computación. Cursos de verano 2010. Computación de altas prestaciones con GPUs. Enrique Arias Antúnez José Luis Sánchez García. Índice. Introducción Arquitectura CUDA Modelo de ejecución Programación Rendimiento. Computación de altas prestaciones. - PowerPoint PPT PresentationTRANSCRIPT
![Page 1: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/1.jpg)
Computación de altas prestaciones con GPUs
Cursos de
verano 2010
Enrique Arias Antúnez
José Luis Sánchez García
Presente y futuro de los sistemas de computación
1
![Page 2: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/2.jpg)
Índice
• Introducción• Arquitectura CUDA• Modelo de ejecución• Programación• Rendimiento
2
![Page 3: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/3.jpg)
Computación de altas prestaciones
• Los grandes supercomputadores son la única alternativa para cierto tipo de aplicaciones
• Sin embargo, hay aplicaciones con menos exigencias computacionales
• GPGPU– Utilizar GPUs para aplicaciones
de propósito general– Muy atractivo en términos de
rendimiento, consumo y coste– Exclusividad
3
![Page 4: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/4.jpg)
Introducción
Rendimiento
Fuente: Nvidia 4
![Page 5: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/5.jpg)
Introducción
2 x Xeon QuadCore 2 x Xeon QuadCore + Tesla s1070
Cores 8 8 + 240*4 = 968
Rendimiento pico (sp) 0,17 TFlops 4,14 TFlops
Rendimiento pico (dp) 0,08 TFlops 0,35 TFlops
Precio 2400 euros 9000 euros
Consumo 700 W 1500 W
Precios
Más de 100 millones de GPUs de Nvidia
5
![Page 6: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/6.jpg)
Introducción
Uso de los transistores
+ Cache
+ Control
- Cores
+ Cores
- Cache
- Control 6
![Page 7: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/7.jpg)
Introducción
Aplicación Descripción Código Kernel % tiempo
H.264 SPEC ‘06 version, change in guess vector 34.811 194 35%
LBM SPEC ‘06 version, change to single precision and print fewer reports
1.481 285 >99%
RC5-72 Distributed.net RC5-72 challenge client code
1.979 218 >99%
FEM Finite element modeling, simulation of 3D graded materials
1.874 146 99%
RPES Rye Polynomial Equation Solver, quantum chem, 2-electron repulsion
1.104 281 99%
PNS Petri Net simulation of a distributed system 322 160 >99%
SAXPY Single-precision implementation of saxpy, used in Linpack’s Gaussian elim. routine
952 31 >99%
TRACF Two Point Angular Correlation Function 536 98 96%
FDTD Finite-Difference Time Domain analysis of 2D electromagnetic wave propagation
1.365 93 16%
MRI-Q Computing a matrix Q, a scanner’s configuration in MRI reconstruction
490 33 >99%7
![Page 8: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/8.jpg)
Introducción
0
10
20
30
40
50
60
H.264 LBM RC5-72 FEM RPES PNS SAXPY TPACF FDTD MRI-Q MRI-FHD
KernelApplication
210 457431
316263
GP
U S
pee
dup
Rel
ativ
e to
CP
U
79
• GeForce 8800 GTX vs. 2.2GHz Opteron 248 • 10 speedup en un kernel es típico, si hay suficiente paralelismo• 25 a 400 speedup con optimizaciones• Depende mucho del tipo de aplicación
8
![Page 9: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/9.jpg)
Introducción
Programabilidad
2005 2009
Ensamblador
OpenGL
DirectX
Cg
Brook++
RapidMind
CUDA OpenCL
Fac
ilida
d de
pr
ogra
mac
ión
Inicios GPGPUATI Stream
Explosión GPGPU
Futuro GPGPU?
9
![Page 10: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/10.jpg)
Índice
Introducción• Arquitectura CUDA• Modelo de ejecución• Programación• Rendimiento
10
![Page 11: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/11.jpg)
Arquitectura CUDA
. . .
Memoria global
Conjunto de Streaming Multiprocessors (MP)
SP
DP
SM
8 Scalar Processors (SP)
1 Unidad de Doble Precisión (DP)
16 KB de Memoria Compartida (SM)
8-16 K Registros11
![Page 12: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/12.jpg)
Fermi
~1.5TFLOPS (SP)~800GFLOPS (DP)230 GB/s DRAM
12
![Page 13: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/13.jpg)
Espacios de memoria en CUDA
13
Fuente: Nvidia
![Page 14: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/14.jpg)
Espacios de memoria en CUDA
Memoria Localización Cache Acceso Ámbito Vida
Registros On-chip N/A R/W Un thread Thread
Compartida On-chip N/A R/W Threads en bloque
Bloque
Global Off-chip No R/W Todos threads y host
Aplicación
Constantes Off-chip Sí R Todos threads y host
Aplicación
Texturas Off-chip Sí R Todos threads y host
Aplicación
14
![Page 15: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/15.jpg)
Gestión de memoria con CUDA
• CPU y GPU tienen espacios de memoria independientes
• Transferencia de datos entre ambos espacios de memoria a través del bus PCIExpress
• Reserva, transferencia y liberación explícitas
• Las operaciones con memoria realizadas por el host
15Fuente: Nvidia
![Page 16: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/16.jpg)
Gestión de memoria con CUDA
• cudaMalloc()– Obtiene espacio en la
memoria global– Parámetros: dirección del
puntero y el tamaño a reservar• cudaMemset()
– Inicializa a un valor dado– Parámetros: dirección, valor y
cantidad• cudaFree()
– Libera el espacio– Parámetros: dirección
16Fuente: Nvidia
![Page 17: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/17.jpg)
Gestión de memoria con CUDA
• cudaMemcpy()– Transfiere datos entre
memorias– Requiere 4 parámetros:
• Puntero al destino• Puntero al origen• Bytes a copiar• Tipo de transferencia:
– Host a host– Host a dispositivo– Dispositivo a host– Dispositivo a dispositivo
17Fuente: Nvidia
![Page 18: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/18.jpg)
• Ejemplo– Reservar, inicializar y liberar espacio para una matriz
64x64 de elementos float– Enlazar ese espacio a Md
Gestión de memoria con CUDA
#define BLOCK_SIZE 64float * Md;int size = BLOCK_SIZE*BLOCK_SIZE*sizeof(float);cudaMalloc((void**)&Md,size);cudaMemset(Md,0,size); . . .cudaFree(Md);
18
![Page 19: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/19.jpg)
• Ejemplo– Transferir una matriz de 64x64 float de la memoria
de la GPU a la del host y viceversa– Matriz M está en el host y la matriz Md en el
dispositivo
Gestión de memoria con CUDA
cudaMemcpy(M,Md,size,cudaMemcpyDeviceToHost);
cudaMemcpy(Md,M,size,cudaMemcpyHostToDevice);
19
![Page 20: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/20.jpg)
Índice
IntroducciónArquitectura CUDA• Modelo de ejecución• Programación• Rendimiento
20
![Page 21: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/21.jpg)
Modelo de ejecución
Secuencial
Código
Thread
21
![Page 22: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/22.jpg)
Modelo de ejecución
Paralelo
Código
Threads
22
![Page 23: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/23.jpg)
kernel
Paralelo
Miles de threads
lanzados a la vez
23
![Page 24: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/24.jpg)
Modelo de ejecución
Memoria
Kernel Threads (instancias del
kernel)PCIe
CPU GPU
24
![Page 25: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/25.jpg)
Modelo de ejecución
CPU GPU
• Cada thread tiene un identificador• Todos los threads ejecutan el mismo código• Cada thread opera sobre distintos datos
• Modelo SIMD
CPU
• Threads pesados• Sobrecarga
planificación• Cambios de
contexto lentos
CPU
• Threads ligeros• Poca sobrecarga
planificación• Cambios de
contexto rápidos
25
![Page 26: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/26.jpg)
Estructura jerárquica de threads
• Los threads se agrupan en bloques de threads• Los bloques de threads se agrupan en Grids• Los threads de un bloque se comunican mediante la
memoria compartida • Todos los threads del Grid se comunican a través de
la memoria global
• Un thread se ejecuta en un procesador escalar (SP)• Un bloque de threads se lanza en un
multiprocesador (MP)• Un MP puede desarrollar varios bloques
Grid 1
Bloque(2,1)
Bloque(2,0)
Bloque(0,0)
Bloque(1,0)
Bloque(0,1)
Bloque(1,1)
Thread(0,0)
Thread(1,0)
Thread(2,0)
Thread(3,0)
Thread(4,0)
Thread(0,1)
Thread(1,1)
Thread(2,1)
Thread(3,1)
Thread(4,1)
Thread(0,2)
Thread(1,2)
Thread(2,2)
Thread(3,2)
Thread(4,2)
Bloque (1,1)
26
![Page 27: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/27.jpg)
Modelo de ejecución
Software Hardware
Thread SP
• Un bloque se ejecuta en un MP• Los bloques no migran entre MPs• Varios bloques a la vez en un MP
(según registros y memoria compartida)
Bloque threads MP
…
Grid GPU
• Un único kernel concurrente
• Cada thread se ejecuta en un SP
27
![Page 28: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/28.jpg)
Indentificadores y dimensiones
• El tamaño del grid y de los bloques los determina el programador
• Se usan las variables gridDim y blockDim para referenciar la dimensión de grid y bloque, respectivamente
Grid 1
Bloque(2,1)
Bloque(2,0)
Bloque(0,0)
Bloque(1,0)
Bloque(0,1)
Bloque(1,1)
Thread(0,0)
Thread(1,0)
Thread(2,0)
Thread(3,0)
Thread(4,0)
Thread(0,1)
Thread(1,1)
Thread(2,1)
Thread(3,1)
Thread(4,1)
Thread(0,2)
Thread(1,2)
Thread(2,2)
Thread(3,2)
Thread(4,2)
Bloque (1,1)
gridDim.x
grid
Dim
.y
• Un thread queda indentificado por:– Un identificador propio dentro del bloque al que
pertenece– El identificador del bloque al que pertenece
• Se usan las variables threadIdx y blockIdx para referenciar el identificador del thread dentro del bloque y al bloque dentro del grid, respectivamente
blockDim.x
blo
ckD
im.y
blockDim.z
blockIdx.x=1blockIdx.y=1
threadIdx.x=0threadIdx.y=2
28
![Page 29: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/29.jpg)
Planificación
• Se agrupan los threads en bloques• Se asignan identificadores a bloques y threads• Se distribuyen los bloques de threads entre los
multiprocesadores• Los threads de un bloque se ejecutan
concurrentemente en un multiprocesador
tiem
po
warp 8 instrucción 11
warp 1 instrucción 42
warp 3 instrucción 95
warp 8 instrucción 12
...
warp 3 instrucción 96
Bloque 1 Bloque 2 Bloque n
warp 12
m
warp 12
m
warp 12
m
• Los threads de un bloque son agrupados en warps• Un warp es la unidad mínima de planificación y está
formada por 32 threads• Varios warps en cada multiprocesador, pero sólo
uno está en ejecución en cada momento• Los warps cuyos operandos están listos son
seleccionados para ejecución• Todos los threads en un warp ejecutan la misma
instrucción29
![Page 30: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/30.jpg)
Planificación• Tres flujos de instrucciones:
warp1, warp3 y warp8
t=k
t=k+1
t=k+2
t=l>k
t=l+1
Warp Instrucciónactual
Estado de laInstrucción
Warp 1 42 Computando
Warp 3 95 Computando
Warp 8 11 Operandos preparados
…
Planificaen tiempo k
warp 8 instrucción 11
warp 1 instrucción 42
warp 3 instrucción 95
warp 8 instrucción 12
...
warp 3 instrucción 96
30
![Page 31: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/31.jpg)
Planificación
warp 8 instrucción 11
warp 1 instrucción 42
warp 3 instrucción 95
warp 8 instrucción 12
...
warp 3 instrucción 96
t=k
t=k+1
t=k+2
t=l>k
t=l+1
Warp CurrentInstruction
InstructionState
Warp 1 42 Preparadoescribir result.
Warp 3 95 Computando
Warp 8 11 Computando
…
Planifica entiempo k+1
• Tres flujos de instrucciones: warp1, warp3 y warp8
31
![Page 32: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/32.jpg)
Índice
IntroducciónArquitectura CUDAModelo de ejecución• Programación• Rendimiento
32
![Page 33: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/33.jpg)
Programación
• Computación heterogénea– Parte de código se ejecuta en la CPU– Parte de código se ejecuta en la GPU (kernel)
• La API de CUDA es una extensión al lenguaje ANSI C– Curva de aprendizaje suave
• Extensiones básicas– Modificadores de función– Modificadores de variables– Variables específicas de dimensionado– Directiva para ejecución del kernel
33
![Page 34: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/34.jpg)
Modificadores de función
Indica dónde se ejecuta la función: GPU (device) o CPU (host)
__device__ La función debe ejecutarse en el dispositivo
• Sólo puede ser llamada por el propio dispositivo
• Recursividad no soportada
• No pueden declararse variables estáticas dentro de la función
• La función no puede tener un número variable de argumentos
__global__ La función es un kernel que debe ejecutarse en el dispositivo
• Sólo puede ser llamada por el host
• Recursividad no soportada
• No pueden declararse variables estáticas dentro de la función
• La función no puede tener un número variable de argumentos
• La función debe devolver siempre void
__host__ La función debe ejecutarse en el host
• Sólo puede ser llamada por el host
• No puede utilizarse junto con __global__
34
![Page 35: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/35.jpg)
Modificadores de variables
Indica en qué parte de la memoria se localiza la variable
__device__ La variable reside en el dispositivo
• Requiere que se indique uno de los otros dos modificadores de variables para indicar dónde exactamente reside la variable en el dispositivo
__constant__ La variable reside en el espacio de memoria constante del dispositivo
• Está viva durante todo el tiempo de ejecución de la aplicación• Accesible por todos los threads del grid, así como desde el host
__shared__ La variable reside en el espacio de memoria compartida del bloque de threads en el dispositivo
• Está viva mientras el bloque está vivo• Accesible sólo por los threads del bloque
35
![Page 36: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/36.jpg)
Variables específicas dimensiones
Indican las dimensiones que caracterizan a los identificadores de los threads y bloques
• dim3 gridDim;
– Dimensiones de los grids en bloques (gridDim.z no usado)
• dim3 blockDim;
– Dimensiones del bloque en threads
• dim3 blockIdx;
– Indice del bloque en el grid
• dim3 threadIdx;
– Indice del thread en el bloque
36
![Page 37: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/37.jpg)
Directiva ejecución del kernel
Indica cómo debe ejecutarse el kernel en el dispositivo
– Cada vez que se llama a __global__, también debe especificarse la configuración de ejecución del kernel
– Se inserta entre el nombre de la función y el paréntesis del argumento una expresión de la forma: <<< Dg, Db, Ns, S >>>
• Dg: indica las dimensiones de la malla, es decir, la cantidad de bloques• Db: indica las dimensiones de cada bloque, es decir, el número de threads por
bloque• Ns: indica el número de bytes de memoria compartida asignada dinámicamente
por bloque (argumento opcional, 0 por defecto)• S: especifica un stream (argumento opcional, 0 por defecto)
– Las invocaciones de kernels son asíncronas• El control vuelve al programa principal (CPU)
37
![Page 38: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/38.jpg)
Ejecución del kernel
• Un kernel debe ser ejecutado del siguiente modo:
__global__ void KernelFunction(…);
dim3 DimGrid(100,50); // 5000 bloques
dim3 DimBlock(4,8,8); // 256 threads/bloque
KernelFunction<<< Dimgrid,Dimblock >>>(…);
38
![Page 39: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/39.jpg)
Ejemplo: SAXPY// Definición de la funciónvoid saxpy_serial (int n, float a, float *x, float *y){ for (int i = 0; i < n; ++i) y[i] = a*x[i] + y[i];}
// Llamada a la funciónsaxpy(n,2.0,x,y)
// Definición del kernel__global__ void saxpy_parallel (int n, float a, float *x, float *y){ int i = blockIdx.x*blockDim.x + threadIdx.x; if (i < n) y[i] = a*x[i] + y[i];}
// Llamada al kernelint nblocks = (n + 255) / 256;saxpy_parallel<<<nblocks, 256>>>(n, 2.0, x, y); 39
![Page 40: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/40.jpg)
Índice
IntroducciónArquitectura CUDAModelo de ejecuciónProgramación• Rendimiento
40
![Page 41: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/41.jpg)
Optimizaciones
• Reducir sobrecargas en el acceso a memoria– Realizar transferencias asíncronas– Mejorar accesos a memoria global– Usar memoria compartida– Reducir conflictos de bancos en memoria compartida
• Configurar la ejecución– Seleccionar el número de bloques y threads por bloque
• Optimizar a nivel de instrucción– Instrucciones aritméticas– Instrucciones para acceso a memoria– Saltos y sentencias condicionales
41
![Page 42: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/42.jpg)
Transferencias asíncronas
• cudaMemcpy es bloqueante– Se devuelve el control al host una vez finalizada la
transferencia
• cudaMemcpyAsync es no bloqueante– Se devuelve el control inmediatamente
• Las transferencias no bloqueantes permiten solapar computación y comunicación
42
![Page 43: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/43.jpg)
Solapar computación y comunicación
• Un stream es un conjunto de operaciones que se completan secuencialmente
• Se puede solapar la comunicación y computación de diferentes streams
• Para ello se debe permitir que la memoria del host esté mapeada en el espacio de direcciones del dispositivo
43
Datos2Datos1
Datos2Datos1
Host→Device Device→HostKernel Cálculos
Datos1 Datos2
Datos2
Host→Device
Device → Host
Kernel Cálculos
Datos1 Datos2
Datos1 Datos2
Datos1
43
![Page 44: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/44.jpg)
Memoria global
• Latencia alta– Usarla lo menos posible
• Accesos por half-warp (16 threads)– Intentar completarlos en el menor número de transacciones
posible (coalescing)
1 transacción 16 transacciones
44
![Page 45: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/45.jpg)
Memoria global
• Latencia alta– Usarla lo menos posible
• Accesos por half-warp (16 threads)– Intentar completarlos en el menor número de transacciones
posible (coalescing)
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
1
2
3
4
5
6
7
8
…
memoria globalmatriz
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
1
2
3
4
5
6
7
8
…
memoria globalmatriz
45
![Page 46: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/46.jpg)
Memoria compartida• Dividida en módulos (bancos) • En las GPUs actuales hay 16 bancos de 1KB• Acceso simultáneo a los bancos• Baja latencia (similar registros)• Problema: conflictos en los bancos (acceso al mismo banco por dos o más threads)
Banco 0
Banco 1
Banco 2
Banco 3
Banco 4
Banco 14
Banco 15
Thread 0
Thread 1
Thread 2
Thread 3
Thread 4
Thread 14
Thread 15
. . .. . .
Sin conflictos
Direccionamiento linealStride = 1
Banco 0
Banco 1
Banco 2
Banco 3
Banco 4
Banco 14
Banco 15
Thread 0
Thread 1
Thread 2
Thread 3
Thread 4
Thread 14
Thread 15
. . .. . .
Sin conflictos
Direccionamiento aleatorioPermutación 1:1
Banco 0
Banco 1
Banco 2
Banco 3
Banco 4
Banco 5
Banco 15
Thread 0
Thread 1
Thread 2
Thread 3
Thread 8
Thread 15
. . .
. . .
. . .Thread 9
Con conflictos
Direccionamiento linealStride = 2
46
![Page 47: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/47.jpg)
Memoria compartida• Dividida en módulos (bancos) • En las GPUs actuales hay 16 bancos de 1KB• Acceso simultáneo a los bancos• Baja latencia (similar registros)• Problema: conflictos en los bancos (acceso al mismo banco por dos o más threads)
• Cargar los datos desde la memoria global a la memoria compartida
• Sincronizar threads
• Procesar usando sólo memoria compartida
• Sincronizar
• Llevar resultados a memoria global
47
![Page 48: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/48.jpg)
Bloques y threads• Ocupación:
– Número de warps activos por MP con respecto al máximo posible de warps activos
• El número total de bloques y de threads por bloque son factores importantes
• Número de bloques– Dependiente de los recursos disponibles– Al menos tantos como MPs– Más de uno por MP para que unos mantengan los recursos ocupados mientras
otros se sincronizan– Suficientemente alto para escalar en futuras versiones
• Número de threads por bloque– Múltiplo del tamaño del warp para facilitar coalescing– Múltiplos de 64, para evitar conflictos en acceso a registros– Entre 128 y 256 buena elección – Más threads no implica necesariamente mayor ocupación
• Experimentación
48
![Page 49: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/49.jpg)
Rendimiento a nivel de instrucción
• La productividad a nivel de instrucción depende de– Número de operaciones– Latencia de la memoria– Ancho de banda de la memoria
• Maximizar ancho de banda efectivo– Maximizar el uso de la memoria compartida– Minimizar los accesos a memoria global– Maximizar coalescing en los accesos a memoria global– Solapar comunicación y computación
• Aumentar el rendimiento de la ejecución de las instrucciones– Instrucciones aritméticas más rápidas, si se prefiere velocidad en lugar
de precisión– Instrucciones para accesos a memoria con menos latencia– Evitar sentencias condicionales que generen diferentes caminos en el
mismo warp, pues éstos son serializados
49
![Page 50: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/50.jpg)
Divergencia de caminos
Branch
Path A
Path B
Salto
Path A
Path B
• Los caminos son serializados
• Incremento del número de instrucciones ejecutadas por el warp
• Los threads vuelven a converger cuando todos los caminos se completan
• 50% de pérdida de rendimiento
50
![Page 51: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/51.jpg)
Índice
• Producto Matriz-Matriz• ¿Cómo explotar más la arquitectura?• Buenas prácticas de programación
CUDA• OpenCL
51
![Page 52: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/52.jpg)
Índice
• Producto Matriz-Matriz– Implementación secuencial– Recordar– Implementación básica– ¿Cómo compilar?– Implementación memoria compartida
• ¿Cómo explotar más la arquitectura?• Buenas prácticas de programación
CUDA• OpenCL
52
![Page 53: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/53.jpg)
Producto Matriz-Matriz
• Implementación secuencial
53
![Page 54: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/54.jpg)
Producto Matriz-Matriz
• cudaMalloc()• cudaMemcpy()• cudaThreadSynchronize();• cudaFree()• multiplication<<< grid, threads >>>(d_P, d_M, d_N,
M.width, N.width);• __global__ void multiplication(float *P, float *M, float *N,
int wM, int wN)
54
![Page 55: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/55.jpg)
Producto Matriz-Matriz
• Implementación básica– Cada thread calcula un
elemento de la matriz• Lee una fila de A• Lee una columna de B
55
![Page 56: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/56.jpg)
Producto Matriz-Matriz
• Implementación básica– Ejercicio 1: (En programa principal)
• a) Repasar las llamadas y el significado • b) Completar llamada a kernel• c) Cálculo de GigaFlops
– Ejercicio 2: (En kernel)• a) Cálculo de índices• b) Cálculo de elemento
– Ejercicio 3: (Pruebas)
56
![Page 57: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/57.jpg)
Producto Matriz-Matriz• Implementación básica
– Ejercicio 2.a (Ejemplo)
57
(0,0) (1,0) (2,0)
(0,1) (1,1) (2,1)
(0,2) (1,2) (2,2)
(0,0) (1,0) (2,0)
(0,1) (1,1) (2,1)
(0,2) (1,2) (2,2)
(0,0) (1,0) (2,0)
(0,1) (1,1) (2,1)
(0,2) (1,2) (2,2)
(0,0) (1,0) (2,0)
(0,1) (1,1) (2,1)
(0,2) (1,2) (2,2)
(0,0) (1,0) (2,0)
(0,1) (1,1) (2,1)
(0,2) (1,2) (2,2)
(0,0) (1,0) (2,0)
(0,1) (1,1) (2,1)
(0,2) (1,2) (2,2)
5
3(0,0) (1,0)
(0,1) (1,1)
(0,2) (1,2)
![Page 58: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/58.jpg)
Producto Matriz-Matriz• ¿Cómo compilar?
gmultiply: gmultiply.cu
nvcc gmultiply.cu
-keep
--ptxas-options=-v
-o gmultiply
-lcutil
-L /usr/local/cuda/sdk/lib
-I /usr/local/cuda/sdk/common/inc58
![Page 59: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/59.jpg)
GPU GeForce 285GTX
• 30 multiprocesadores (MPs)– 8 cores (FPUs) por multiprocesador, a 1476 MHz– mad: multiplicación-suma (considera 2 flops a efectos de cálculo de productividad) – 2 SFU (unidades funcionales especiales) por multiprocesador
• Total 240 cores
• 797 GFLOPS (rendimiento pico)– (30 MPs) x (8x2 + 2 Flops/MP) x 1476 MHz = 797 GFLOPS
• 1GB RAM– 1242 MHz (double data rate, 2484 MHz)– 512 bits (ancho bus)– 159 GB/s = (2484 MHz) x (512 / 8 bytes)
59
![Page 60: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/60.jpg)
Producto Matriz-Matriz
• Se usan los cores (no las SFUs)– (240 cores) x 1476 MHz =
= 354,24 Goperaciones/s
• De 8 instrucciones sólo 2 son FLOP• Máxima productividad
– 354,24 x ¼ = 88,56 GLOPS
• ¿Por qué no se llega a ese valor?
60
$Lt_0_7:
ld.global.f32 %f2, [%r15+0];
ld.global.f32 %f3, [%r17+0];
mad.f32 %f1, %f2, %f3, %f1;
add.s32 %r17, %r17, 4096;
add.s32 %r15, %r15, 4;
setp.ne.u32 %p1, %r15, %r16;
@%p1 bra $Lt_0_7;
• Accesos a memoria– ¼ operaciones son cargas– (240 cores) x (¼ cargas) x (4bytes/carga) x (1476 MHz) = 354 GBs > 159 GBs
El ancho de banda con memoria global no es suficiente
![Page 61: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/61.jpg)
Producto Matriz-Matriz
• Cada dato de entrada es leído por width threads
• Latencia memoria global ~ 400 ciclos• Latencia memoria compartida ~ 10 ciclos
• Llevar cada dato de entrada a memoria compartida y que sea leído por varios threads
61
![Page 62: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/62.jpg)
Producto Matriz-Matriz
• Cada dato de entrada es leído por width threads
• Latencia memoria global ~ 400 ciclos• Latencia memoria compartida ~ 10 ciclos
• Llevar cada dato de entrada a memoria compartida y que sea leído por varios threads
Producto de sub-matrices
• Cada sub-matriz es calculada por un bloque de threads
• Los datos de entrada necesarios son llevados a memoria compartida 62
![Page 63: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/63.jpg)
Producto Matriz-Matriz
• Implementación memoria compartida– Disminuir accesos a
memoria– ¿Cómo lo haríais?
63
![Page 64: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/64.jpg)
Producto Matriz-Matriz
64
C1,0C0,0
C0,1
C2,0 C3,0
C1,1
C0,2 C2,2 C3,2C1,2
C3,1C2,1
C0,3 C2,3 C3,3C1,3
A2,0
A1,1
A1,0A0,0
A0,1
A3,0
A2,1 A3,1
A2,2
A1,3
A1,2A0,2
A0,3
A3,2
A2,3 A3,3
B0,3 B1,3
B1,2
B1,1
B1,0B0,0
B0,1
B0,2
B2,3 B3,3
B3,2
B3,1
B3,0B2,0
B2,1
B2,2
![Page 65: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/65.jpg)
Producto Matriz-Matriz
65
C0,0
thread0,0
C1,0
thread1,0
C0,1
thread0,1
C1,1
thread1,1
A0,0 x B0,0 A0,0 x B1,0 A0,1 x B0,0 A0,1 x B1,0
A1,0 x B0,1 A1,0 x B1,1 A1,1 x B0,1 A1,1 x B1,1
A2,0 x B0,2 A2,0 x B1,2 A2,1 x B0,2 A2,1 x B1,2
A3,0 x B0,3 A3,0 x B1,3 A3,1 x B0,3 A3,1 x B1,3
orde
n ac
ceso
s
En una primera fase se llevan a memoria compartida
En una segunda fase se llevan a memoria compartida
Cada Ai,j y Bi,j se lee dos veces
Cada thread calcula un punto de la matriz resultado
![Page 66: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/66.jpg)
Producto Matriz-Matriz
66
C1,0C0,0
C0,1
C2,0 C3,0
C1,1
C0,2 C2,2 C3,2C1,2
C3,1C2,1
C0,3 C2,3 C3,3C1,3
A2,0
A1,1
A1,0A0,0
A0,1
A3,0
A2,1 A3,1
A2,2
A1,3
A1,2A0,2
A0,3
A3,2
A2,3 A3,3
B0,3 B1,3
B1,2
B1,1
B1,0B0,0
B0,1
B0,2
B2,3 B3,3
B3,2
B3,1
B3,0B2,0
B2,1
B2,2
(1,1)
(1,0)(0,0)
(0,1)
threads
C0,0 C1,0
C1,1C0,1
calculan
memoria compartida
As Bs
cada thread lleva un dato de A y B
![Page 67: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/67.jpg)
Producto Matriz-Matriz
67
C1,0C0,0
C0,1
C2,0 C3,0
C1,1
C0,2 C2,2 C3,2C1,2
C3,1C2,1
C0,3 C2,3 C3,3C1,3
A2,0
A1,1
A1,0A0,0
A0,1
A3,0
A2,1 A3,1
A2,2
A1,3
A1,2A0,2
A0,3
A3,2
A2,3 A3,3
B0,3 B1,3
B1,2
B1,1
B1,0B0,0
B0,1
B0,2
B2,3 B3,3
B3,2
B3,1
B3,0B2,0
B2,1
B2,2
(1,1)
(1,0)(0,0)
(0,1)
threads
C0,0 C1,0
C1,1C0,1
calculan
memoria compartida
As Bs
A0,0 A1,0
A1,1A0,1
B0,0 B1,0
B1,1B0,1
C0,0 = A0,0 x B0,0 + A1,0 x B0,1
C1,0 = A0,0 x B1,0 + A1,0 x B1,1
C0,1 = A0,1 x B0,0 + A1,1 x B0,1
C1,1 = A0,1 x B1,0 + A1,1 x B1,1
![Page 68: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/68.jpg)
Producto Matriz-Matriz
68
C1,0C0,0
C0,1
C2,0 C3,0
C1,1
C0,2 C2,2 C3,2C1,2
C3,1C2,1
C0,3 C2,3 C3,3C1,3
A2,0
A1,1
A1,0A0,0
A0,1
A3,0
A2,1 A3,1
A2,2
A1,3
A1,2A0,2
A0,3
A3,2
A2,3 A3,3
B0,3 B1,3
B1,2
B1,1
B1,0B0,0
B0,1
B0,2
B2,3 B3,3
B3,2
B3,1
B3,0B2,0
B2,1
B2,2
(1,1)
(1,0)(0,0)
(0,1)
threads
C0,0 C1,0
C1,1C0,1
calculan
memoria compartida
As Bs
A2,0 A3,0
A3,1A2,1
B0,2 B1,2
B1,3B0,3
C0,0 = A0,0 x B0,0 + A1,0 x B0,1 + A2,0 x B0,2 + A3,0 x B0,3
C1,0 = A0,0 x B1,0 + A1,0 x B1,1 + A2,0 x B1,2 + A3,0 x B1,3
C0,1 = A0,1 x B0,0 + A1,1 x B0,1 + A2,1 x B0,2 + A3,1 x B0,3
C1,1 = A0,1 x B1,0 + A1,1 x B1,1 + A2,1 x B1,2 + A3,1 x B1,3
![Page 69: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/69.jpg)
Producto Matriz-Matriz
• Bloque de threads 16 x 16 = 256 threads• Width = 4096 256 x 256 = 65536 bloques de threads• • Cada dato en una sub-matriz es leído por 16 threads• Los accesos a memoria global se reducen en un factor 16
al usar memoria compartida• Se requiere ahora 354 / 16 ~ 22 GBs
Ahora la memoria no es motivo para no alcanzar la productividad deseada
![Page 70: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/70.jpg)
Producto Matriz-Matriz
• Implementación memoria compartida– Ejercicio 1: (En programa principal)
• a) Repasar las llamadas y el significado • b) Completar llamada a kernel• c) Cálculo de GigaFlops
– Ejercicio 2: (En kernel)• a) Cálculo de índices• b) Cálculo de elemento
– Ejercicio 3: (Pruebas)
70
![Page 71: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/71.jpg)
Producto Matriz-Matriz
• Implementación memoria compartida– Disminuir accesos a
memoria– ¿Cómo lo haríais?– Veamos el código
ahora e identifiquemos los diferentes elementos
71
![Page 72: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/72.jpg)
Índice
Producto Matriz-Matriz• ¿Cómo explotar más la
arquitectura?• Buenas prácticas de programación
CUDA• OpenCL
72
![Page 73: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/73.jpg)
¿Cómo explotar más la arquitectura?
• Sistemas Distribuidos mediante MPI
• Sistemas compartidos mediante OpenMP
73
![Page 74: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/74.jpg)
Índice
Producto Matriz-Matriz¿Cómo explotar más la
arquitectura?• Buenas prácticas de programación
CUDA• OpenCL
74
![Page 75: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/75.jpg)
Guía de buenas prácticas de programación CUDA
• Maximizar ejecución paralela• Optimizar el uso de la memoria
de cara obtener un mayor ancho de banda en el acceso a memoria
• Optimizar el uso de las instrucciones para conseguir una mayor productividad
75
![Page 76: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/76.jpg)
Índice
Producto Matriz-Matriz¿Cómo explotar más la
arquitectura?Buenas prácticas de programación
CUDA• OpenCL
– ¿Qué es OpenCL?– ¿Qué diferencia OpenCL de CUDA?– Ejemplo: Suma de vectores
76
![Page 77: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/77.jpg)
¿Qué es OpenCL?
• OpenCL: Open Computing Language
• Propuesto por a
• ¿Quién está involucrado?
![Page 78: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/78.jpg)
¿Qué diferencia OpenCL de CUDA? (I)
• Punteros– CUDA
struct Node {Node* next}
n=n->next
– Openclstruct Node {unsigned int next;}
next=bufBase+n
![Page 79: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/79.jpg)
¿Qué diferencia OpenCL de CUDA? (II)
• Kernels– CUDA
• Programa compilado en formato binario
– OpenCL• Se compila en tiempo de
ejecución
– Palabras Clave y lenguaje utilizado para los kernel
![Page 80: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/80.jpg)
Ejemplo: Suma de vectores
• CUDA_global_ void
SumaVec(const float *a, const float *b, float *c)
// Índice al elemento del vector
int indice=blockIdx.x*blockDim.x+threadIdx.x
c[indice]=a[indice]+b[indice]
}
• OpenCL_kernel void
SumaVec(_global const float *a, _global const float *b, _global float *c)
// Índice al elemento del vector
int indice=get_global_id(0)
c[indice]=a[indice]+b[indice]
}
![Page 81: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/81.jpg)
Índice
Producto Matriz-Matriz¿Cómo explotar más la
arquitectura?Buenas prácticas de programación
CUDAOpenCL
81
![Page 82: Computación de altas prestaciones con GPUs](https://reader035.vdocuments.mx/reader035/viewer/2022081504/568144bc550346895db18434/html5/thumbnails/82.jpg)