O documento discute arquiteturas de computação paralela avançadas como CUDA e OpenCL. Explica o que é CUDA, sua história, arquitetura de GPU, modelo de memória e programação. Também aborda OpenCL e aplicações dessas tecnologias em ciência de dados e computação científica.
1. CUDA/OpenCL
Arquiteturas Avancadas de Computadores
Krissia de Zawadzki
Instituto de F´ısica de S˜ao Carlos - Universidade de S˜ao Paulo
06 de Maio 2014
Krissia de Zawadzki CUDA/OpenCL 1 / 61
2. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Outline
1 CUDA - Introduc~ao
2 GPU e CUDA
3 Programando em CUDA
4 OpenCL
5 Caos
6 Conclus~ao
Krissia de Zawadzki CUDA/OpenCL 2 / 61
3. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
CUDA - Introdu¸c˜ao
CUDA
Compute Uni
4. ed Device Architecture
3 Plataforma de computac~ao paralela e
modelo de programac~ao
3 Desenvolvido pela NVIDIA e
implementada para GPU's NVIDIA
3 Conjunto de instruc~oes e memoria
diretamente acessveis ao programador
Krissia de Zawadzki CUDA/OpenCL 3 / 61
5. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Background hist´orico
Background hist´orico
2002: Stanford University
Steam processing
Prototipo e arquitetura muito parecida
com GPU
Baseline programmable
stream processor
Krissia de Zawadzki CUDA/OpenCL 4 / 61
6. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Background hist´orico
Background hist´orico
2002: GeForce 3 e ATI Radeon 9700
3 Shaders programaveis
Krissia de Zawadzki CUDA/OpenCL 5 / 61
7. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Background hist´orico
Background hist´orico
2006: GeForce 8
Arquitetura uni
8. cada → CUDA!
Krissia de Zawadzki CUDA/OpenCL 6 / 61
9. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Background hist´orico
Background hist´orico
2006: GeForce 8
3 Programabilidade realmente
exvel
3 Revolucionou os conceitos de
pipeline de pixel e vertices
3 Cadeia de processadores
Krissia de Zawadzki CUDA/OpenCL 7 / 61
10. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
GPU’s com suporte para CUDA
GPU’s com suporte para CUDA
GeForce 8
3 8, 9, 100, 200, 400, 500 e
600-series (m´ın 256MB memloc)
3 1.0, 1.1, 1.2, 1.3, 2.0, 2.1, 3.0,
3.5 e 5.0
GeForce GTX-750 (5.0)
NVS
3 Quadro 295, 420, 450
3 NVIDIA NVS 300, 315, 510
3 1.1, 1.2, 2.1 e 3.0
NVIDIA NVS 510 (3.0)
Krissia de Zawadzki CUDA/OpenCL 8 / 61
11. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
GPU’s com suporte para CUDA
GPU’s com suporte para CUDA
QUADRO
3 Quadro NVS, Quadro FX, Quadro K
3 1.0, 1.1, 1.2, 1.3, 2.0, 2.1, 3.0 e
3.5
QUADRO K600 (3.5)
Tesla
3 D780, C870, C1060, C2050/2070,
C2075
3 K20, K40
3 1.0, 1.3, 2.0, 3.5
Tesla K20 (3.5)
Krissia de Zawadzki CUDA/OpenCL 9 / 61
12. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Aplica¸c˜oes
Al´em de processamento gr´afico
Krissia de Zawadzki CUDA/OpenCL 10 / 61
13. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Aplica¸c˜oes
Krissia de Zawadzki CUDA/OpenCL 11 / 61
14. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Aplica¸c˜oes
Ganho de desempenho em aplica¸c˜oes cient´ıficas
Krissia de Zawadzki CUDA/OpenCL 12 / 61
15. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
GPU
GPU vs. CPU
CPU
3 C´odigos sequenciais
3 Baixa lat^encia
3 Controle complexo
GPU
3 Paralelismo de dados
3 Alto throughtput
3 Aritm´etica com pouco controle
Krissia de Zawadzki CUDA/OpenCL 13 / 61
16. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
GPU
GPU vs. CPU
CPU
3 Fluxo iterativo
7 Tempo de computa¸c˜ao
7
GPU
3 Opera¸c˜oes simult^aneas
7 Desvio de fluxo
7
Krissia de Zawadzki CUDA/OpenCL 13 / 61
17. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
GPU
CPU vs. GPU
Krissia de Zawadzki CUDA/OpenCL 14 / 61
18. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
GPU
CPU vs. GPU
Krissia de Zawadzki CUDA/OpenCL 14 / 61
19. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Linguagens e modelos de programa¸c˜ao paralela
Linguagens e modelos de programa¸c˜ao paralela
OpenMP
shared memory
limite de centenas de n´os
CUDA
alta escalabilidade
portabilidade ´e mais simples!
MPI
capacidade de n´os 100.000
esfor¸co para portar o c´odigo
OpenCL
modelo de programa¸c˜ao padronizado
suporte para AMD/ATI, NVIDIA,
Apple e Intel
Krissia de Zawadzki CUDA/OpenCL 15 / 61
20. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Arquitetura da GPU
GPU - Unified processor array (GeForce 8800 GTX)
Krissia de Zawadzki CUDA/OpenCL 16 / 61
21. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Estrutura de um programa CUDA
Estrutura de um programa CUDA
Trechos seriais ou com fraco paralelismo no codigo C do host
Porc~ao altamente paralela no codigo C do kernel associado ao device
Krissia de Zawadzki CUDA/OpenCL 17 / 61
22. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Estrutura de um programa CUDA
CUDA Threads paralelas
// de dados: Todas as threads rodam o mesmo codigo
threadIdx: identi
23. cador da thread → de memoria e controle
Krissia de Zawadzki CUDA/OpenCL 18 / 61
24. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Estrutura de um programa CUDA
CUDA Thread Blocks
Thread Blocks: Array (dim 2x2) the threads que cooperam entre si
bloco: memoria compartilhada, operac~oes at^omicas e
barreiras de sincronizac~ao
blockIdx: identi
25. cador do bloco em um grid
Krissia de Zawadzki CUDA/OpenCL 19 / 61
26. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Estrutura de um programa CUDA
CUDA Id’s
Ids s˜ao ´uteis para identificar os
dados sob os quais cada thread ir´a
trabalhar
Conveniente para simplificar o
de mem´oria em dados
multidimensionais
blockIdx:
1D (blockIdx.x)
2D (blockIdx.x, blockIdx.y)
threadIdx:
1D (threadIdx.x),
2D (threadIdx.x, threadIdx.y),
3D (threadIdx.x, threadIdx.y, threadIdx.z)
Krissia de Zawadzki CUDA/OpenCL 20 / 61
27. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Estrutura de um programa CUDA
Par^ametros de configura¸c˜ao
block:
dimBlock ( Widthx , Widthy , , Widthz )
grid:
dimGrid (Wgridx , Wgridy , Wgridz )
Kernel launching
// Setup the execution configuration
dim3 dimBlock (Width , Width , 1);
dim3 dimGrid (1, 1, 1);
// Launch the device computation threads !
MyKernelFunction dimGrid , dimBlock ( args );
Krissia de Zawadzki CUDA/OpenCL 21 / 61
28. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Modelo de Mem´oria CUDA
Modelo de Mem´oria CUDA
Memoria Global:
comunica¸c˜ao host-device
R/W
conte´udo vis´ıvel por todas as
threads
tipicamente implementada
como DRAM
acesso de longa lat^encia
(400-800 ciclos)
7 congestionamento
throughput limitado (a 177
GB/s na GTX8800)
Krissia de Zawadzki CUDA/OpenCL 22 / 61
29. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Modelo de Mem´oria CUDA
Modelo de Mem´oria CUDA
Memoria Constante:
read only
baixa lat^encia e alta largura
de banda quando todas as
threadas acessam o mesmo
local
Krissia de Zawadzki CUDA/OpenCL 22 / 61
30. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Modelo de Mem´oria CUDA
Modelo de Mem´oria CUDA
Memoria Compartilhada:
3 rapida
altamente paralela
apenas um bloco tem acesso
Krissia de Zawadzki CUDA/OpenCL 22 / 61
31. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Modelo de Mem´oria CUDA
Modelo de Mem´oria CUDA
Registradores
3 o componente da memoria
da GPU mais rapido
acess´ıvel por uma threada
Krissia de Zawadzki CUDA/OpenCL 22 / 61
32. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Vari´aveis CUDA
Vari´aveis CUDA
kernel: a vari´avel deve ser declarada no escopo da fun¸c˜ao kernel → fica
dispon´ıvel somente no kernel
application: a vari´avel deve ser declarada fora de qualquer fun¸c˜ao
constant: a vari´avel deve ser declarada fora de qualquer fun¸c˜ao →
limitado (a 64KB na GTX8800)
Krissia de Zawadzki CUDA/OpenCL 23 / 61
33. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
CUDA Kernel Functions
CUDA Kernel Functions
Kernel functions:
implementam o trecho
paralelo de codigo a ser
executado no device
Sua chamada pode ser feita
com as con
35. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
CUDA Kernel Functions
Atribui¸c˜ao de threads
base block-by-block
7 Runtime system
coordena os blocos e as
threads a serem
executadas: mantem a
lista de blocos e associa
novos blocos a SM's
livres
recursos do SM
unidades aritmeticas
numero de threads que
podem ser rastreadas e
escalonadas
simultaneamente
Krissia de Zawadzki CUDA/OpenCL 25 / 61
36. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
CUDA Kernel Functions
CUDA Warps
Warps : conjunto de threads com
ndices consecutivos
A capacidade do warp (num.
de threads) e dependente da
implementac~ao
Warp e a unidade para
escalonar threads no SM
SIMD
ordem qualquer entre warps
7 diverg^encia causada por branchs
Krissia de Zawadzki CUDA/OpenCL 26 / 61
37. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
CUDA Kernel Functions
Compilador NVCC
Baseado no Open64
(opensource originario do
MIPSPro - SGI).
Implementado em C e C++.
NVidia atualmente investindo
no LLVM.
Existe um utilit´ario que
converte LLVM IR (gerado
por qualquer frontend de
compilador LLVM) em PTX,
que pode ser programado nas
GPUs NVidia.
Krissia de Zawadzki CUDA/OpenCL 27 / 61
38. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
CUDA Kernel Functions
Defici^encias
Equipe preferiu implementar codigo para o desa
39. o ECC2K-130
diretamente em codigo de maquina.
BERNSTEIN, D. J. et al. Usable Assembly Language for GPUs: A
Success Story. In: Workshop Records of Special-Purpose Hardware
for Attacking Cryptographic Systems – SHARCS 2012. [s.n.], 2012.
p. 169–178.
Compilador NVCC muito lento para lidar com kernels contendo
muitas instruc~oes.
Registradores alocados de forma pouco e
40. ciente { muitas variaveis
acabaram tendo de ser alocadas pelo NVCC na memoria
compartilhada.
Varios truques necessarios para obter uma implementac~ao em C
aceitavel. Implementac~ao em Assembly 148% mais rapida que
melhor implementac~ao em C.
Krissia de Zawadzki CUDA/OpenCL 28 / 61
41. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Programando em CUDA: exemplo
Multiplica¸c˜ao Matricial: o Hello World do CUDA
푃 = 푀 * 푁
Σ︁
푃푖푗 =
푘
푀푖,푘푁푘,푗
3 Paralelismo de dados!
Cada elemento 푃푖푗 de 푃 pode ser
calculado simultaneamente aos
demais!
Krissia de Zawadzki CUDA/OpenCL 29 / 61
42. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Programando em CUDA: exemplo
Representa¸c˜ao matricial em C
Alocac~ao de memoria no C para arrays bidimensionais:
Krissia de Zawadzki CUDA/OpenCL 30 / 61
43. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Programando em CUDA: exemplo
C´odigo main C sequencial (host)
int main ( void ){
// 1. Alocamos e inicializamos as matrizes M, N e P
// Funcoes I/O leem as matrizes M e N
...
// 2. Multiplicacao M * N
MatMul (M,N,P, Width );
...
// 3. Funcao I/O para escrever a saida P
// Liberamos a memoria de M, N e P
return 0;
}
Krissia de Zawadzki CUDA/OpenCL 31 / 61
44. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Programando em CUDA: exemplo
Fun¸c˜ao C sequencial (host)
void MatMul ( float *M; float *N, float *P, int Width )
{
for ( int i = 0; i Width ; ++i)
for (int j = 0; j Width ; ++j){
float sum = 0;
for ( int k = 0; k Width ; ++k){
float m = M[i* Width + k];
float n = N[k* width + j];
sum += m * n;
}
P[i * Width + j] = sum ;
}
}
Krissia de Zawadzki CUDA/OpenCL 32 / 61
45. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Programando em CUDA: exemplo
Portando o c´odigo para CUDA - aloca¸c˜ao de mem´oria
cudaMalloc()
aloca um objeto na
Memoria Global
par^ametros: endereco de
um ponteiro para o objeto
alocado, tamanho do objeto
cudaFree()
libera um objeto na
Memoria Global
par^ametro: ponteiro para o
objeto
Krissia de Zawadzki CUDA/OpenCL 33 / 61
46. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Programando em CUDA: exemplo
Portando o c´odigo para CUDA - aloca¸c˜ao
Exemplo:
int Width =64;
float * Md , Nd;
int size = Width * Width * sizeof ( float );
cudaMalloc (( void **) Md , size );
cudaMalloc (( void **) Nd , size );
...
cudaFree (Md );
cudaFree (Nd );
Krissia de Zawadzki CUDA/OpenCL 34 / 61
47. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Programando em CUDA: exemplo
Portando o c´odigo para CUDA - transfer^encia de dados
cudaMemcpy()
transfere dados entre o host
e o device
Assncrona
par^ametros:
ponteiro para o destino
ponteiro para a fonte n´umero
de bytes a serem copiados
tipo de transfer^encia
tipos:
Host to Host
Host to Device
Device to Host
Device to Device
Krissia de Zawadzki CUDA/OpenCL 35 / 61
48. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Programando em CUDA: exemplo
Portando o c´odigo para CUDA - transfer^encia de dados
Exemplo:
...
int size = Width * Width * sizeof ( float );
...
cudaMemcpy (Md , M, size , cudaMemcyHostToDevice );
cudaMemcpy (Nd , N, size , cudaMemcyHostToDevice );
...
cudaMemcpy (Pd , P, size , cudaMemcyDeviceToHost );
Krissia de Zawadzki CUDA/OpenCL 36 / 61
49. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Programando em CUDA: exemplo
Portando o c´odigo para CUDA - fun¸c˜ao MatMul no device
void MatMul ( float *M; float *N, float *P, int Width ){
int size = Width * Width * sizeof ( float );
float * Md , Nd , Pd;
// 1. Alocamos memoria no device para M, N e P
cudaMalloc (( void **)) Md , size );
cudaMemcpy (Md , M, size , cudaMemcyHostToDevice );
cudaMalloc (( void **)) Nd , size );
cudaMemcpy (Nd , N, size , cudaMemcyHostToDevice );
cudaMalloc (( void **)) Pd , size );
// 2. Evocamos a funcao kernel para a multiplicacao
// 3. Copiamos o resultado P para a memoria do host
cudaMemcpy (Pd , P, size , cudaMemcyDeviceToHost );
// Liberamos as memorias de M, N e P no device
cudaFree (Md ); cudaFree (Nd ); cudaFree (Pd );
}
Krissia de Zawadzki CUDA/OpenCL 37 / 61
50. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Programando em CUDA: exemplo
Fun¸c˜ao kernel MatMul
Krissia de Zawadzki CUDA/OpenCL 38 / 61
51. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Programando em CUDA: exemplo
Kernel function - um pouco mais sobre especifica¸c˜oes
global de
52. ne uma func~ao kernel
device e host podem ser usadas simultaneamente
7 recurs~oes
7 variaveis estaticas
7 chamadas indiretas de func~oes por ponteiros
Krissia de Zawadzki CUDA/OpenCL 39 / 61
53. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Programando em CUDA: exemplo
Configura¸c˜ao de execu¸c˜ao
Exemplo: De
54. nir a multiplicac~ao matricial quando 푊푖푑푡ℎ = 32 em
blocos Grids 2D com (2x2) blocos Blocos 2D com (16x16) threads
Krissia de Zawadzki CUDA/OpenCL 40 / 61
55. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Programando em CUDA: exemplo
Configura¸c˜ao de execu¸c˜ao
A configura¸c˜ao define a dimens˜ao do problema!!!! No exemplo anterior, usando blocos
1D podemos apenas trabalhar com 푊푖푑푡ℎ = 16 !
Solu¸c˜ao: Manipular dimGrid e dimBlock e dividir o c´alculo de peda¸cos da matriz
resultado entre threads e blocos!
Krissia de Zawadzki CUDA/OpenCL 41 / 61
56. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Programando em CUDA: exemplo
Usando blockIdx e threadIdx
Solu¸c˜ao: tiles!
Krissia de Zawadzki CUDA/OpenCL 42 / 61
57. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Programando em CUDA: exemplo
Usando blockIdx e threadIdx: nova fun¸c˜ao kernel
__global__ void MatMulK ( float *Md , float *Nd , float *Pd , int Width )
{
// linha e colunas do elemento de Pd
int Row = blockIdx .y* TILE_WIDTH + threadIdx .y;
int Col = blockIdx .x* TILE_WIDTH + threadIdx .x;
float Pvalue = 0;
// cada thread calcula um elemento da sub - matriz no bloco
for ( int k = 0; k Width ; ++k)
Pvalue += Md[ Row * Width +k] * Nd[k* Width +Col ];
Pd[ Row * Width + Col ] = Pvalue ;
}
Krissia de Zawadzki CUDA/OpenCL 43 / 61
58. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Programando em CUDA: exemplo
Usando blockIdx e threadIdx: par^ametros de configura¸c˜ao
// configuracao para varios blocos
dim3 dimBlock ( Width / TILE_WIDTH , Width / TILE_WIDTH );
dim3 dimGrid ( TILE_WIDTH , TILE_WIDTH );
// Lancamento do Kernel
MatMulK dimGrid , dimBlock (Md , Nd , Pd , Width );
Krissia de Zawadzki CUDA/OpenCL 44 / 61
59. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Programando em CUDA: exemplo
Sincroniza¸c˜ao
syncthreads()
primitiva chamada por uma
func~ao kernel
o kernel que chamou
60. ca em
espera ate que todas as threads
terminem sua execuc~ao
7 conditionals if-then-else
7 threads em blocos diferentes
n~ao podem sincronizar
Krissia de Zawadzki CUDA/OpenCL 45 / 61
61. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Programando em CUDA: exemplo
Escalabilidade Transparente
3 Potencial para executar o mesmo codigo no hardware com um
numero diferente de recursos de execuc~ao e escalabilidade
transparente.
Krissia de Zawadzki CUDA/OpenCL 46 / 61
62. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Programando em CUDA: exemplo
Usando a mem´oria para obter performance
3 reduzir o tra
63. co de dados da
memoria global evita
congestionamento
3 podemos aproveitar a localidade
de dados para otimizar o acesso
a dados na memoria da GPU
3 Threads que usam dados
comuns podem colaborar!
3 Soluc~ao:
tiling + shared memory
Krissia de Zawadzki CUDA/OpenCL 47 / 61
64. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Programando em CUDA: exemplo
Usando a mem´oria para obter performance
Krissia de Zawadzki CUDA/OpenCL 48 / 61
65. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Programando em CUDA: exemplo
Usando a mem´oria para obter performance
3 Threads 푃1,0 e 푃1,1 compartilham o elemento 푁1,0
3 Threads 푃0,0 e 푃1,0 compartilham o elemento 푁1,0
3 threads com elementos em comum devem estar associadas ao
mesmo bloco e, assim, os dados comuns podem ser guardados na
memoria compartilhada!
Krissia de Zawadzki CUDA/OpenCL 49 / 61
66. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Programando em CUDA: exemplo
Usando a mem´oria para obter performance
3 reduc~ao de tra
67. co de
dados na mem. global
∝ TILE WIDTH
3 P/ NxN blocos, a
reduc~ao ∝ N
3 num. de fases e Width/
TILE WIDTH
Krissia de Zawadzki CUDA/OpenCL 50 / 61
68. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Programando em CUDA: exemplo
Kernel MatMul com mem´oria compartilhada
__global__ voidMatMulK ( float *Md , float *Nd , float *Pd , int Width )
{
__shared__ float Mds [ TILE_WIDTH ][ TILE_WIDTH ];
__shared__ float Nds [ TILE_WIDTH ][ TILE_WIDTH ];
int bx = blockIdx .x; int by = blockIdx .y;
int tx = threadIdx .x; int ty = threadIdx .y;
// Identificamos a linha e a coluna do elemento de Pd
int Row = by * TILE_WIDTH + ty;
int Col = bx * TILE_WIDTH + tx;
float Pvalue = 0;
// Loop sobre os tiles Nd e Md
for ( int m = 0; m Width / TILE_WIDTH ; ++){
Mds [ty ][ tx] = Md[Row * Width + (m* TILE_WIDTH + tx )];
Nds [ty ][ tx] = Nd [(m+ TILE_WIDTH + ty )* Width + Col ];
_syncthreads ();
for ( int k = 0; k TILE_WIDTH ; ++k)
Pvalue += Mds [ty ][k] * Nds[k][ tx]
_syncthreads ();
}
Pd[ Row * Width + Col ] = Pvalue ;
}
Krissia de Zawadzki CUDA/OpenCL 51 / 61
69. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
OpenCL
OpenCL
extens~ao de linguagem e API's
p/ GPU's
applicac~oes OpenCL s~ao
portaveis para todos os
processadores com suporte
3 sintaxe e primitivas semelhantes
ao CUDA
7 performance ≈ CUDA
Krissia de Zawadzki CUDA/OpenCL 52 / 61
70. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
OpenCL - arquitetura do device
OpenCL - arquitetura do device
Krissia de Zawadzki CUDA/OpenCL 53 / 61
71. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
OpenCL e CUDA
OpenCL e CUDA
OpenCL API call Explica¸c˜ao equivalente em CUDA
get global id(0); ´ındice global do work item blockIdx.x ×blocDim.x + threadIdx.x
get local id(0); ´ındice local do work group threadIdx.x
get global size(0); tamanho do range ND gridDim.x ×blocDim.x
get local size(0); tamanho de cada work group blockDim.x
OpenCL conceito de paralelismo equivalente em CUDA
Kernel Kernel
programa Host programa Host
ND range (espa¸co de ´ındice) Grid
work item Thread
work group Block
__kernel void vadd ( __global const float *a, __global const float *b,
__global float * result ){
int id = get_global_id (0) ;
result [id] = a[id ]+b[id ];
}
Krissia de Zawadzki CUDA/OpenCL 54 / 61
72. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Exemplo de c´odigo OpenCL: multiplica¸c˜ao matricial
Exemplo de c´odigo OpenCL: multiplica¸c˜ao matricial
# define BLOCK_SIZE 16
__kernel void
matrixMul ( __global float * P, __global float * M, __global float * N, int Width )
{
int bx = get_group_id (0) , by = get_group_id (1);
int tx = get_local_id (0) , ty = get_local_id (1);
int mBegin = Width * BLOCK_SIZE * by;
int mEnd = aBegin + Width - 1;
int mStep = BLOCK_SIZE ;
int nBegin = BLOCK_SIZE * bx;
int nStep = BLOCK_SIZE * Width ;
for (int m = mBegin , n = nBegin ; m = mEnd ; m += mStep , n += nStep )
{
__local float Ms[ BLOCK_SIZE ][ BLOCK_SIZE ];
__local float Ns[ BLOCK_SIZE ][ BLOCK_SIZE ];
Ms[ty ][ tx] = M[m + Width * ty + tx ];
Ns[ty ][ tx] = N[n + Width * ty + tx ];
barrier ( CLK_LOCAL_MEM_FENCE );
for (int k = 0; k BLOCK_SIZE ; ++k)
Psub += Ms[ty ][k] * Ns[k][ tx ];
barrier ( CLK_LOCAL_MEM_FENCE );
}
int p = Width * BLOCK_SIZE * by + BLOCK_SIZE * bx;
P[p + Width * ty + tx] = Psub ;
}
Krissia de Zawadzki CUDA/OpenCL 55 / 61
73. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Equa¸c˜ao diferencial com caos
Equa¸c˜ao diferencial com caos
¨푥 + 푥3 = sin(Ω푡) (Ω1,Ω2,Ω3, · · · ,Ω푁−1)
푑푥 (푡1, 푡2, · · · , 푡푓 )
= 푢
푑푡
푥0 푢0
integrac~ao
Runge-Kutta 4
· · ·
푑푡1 푑푡
푡0 푡푓
Expoente de Lyapunov
|훿Z(푡)| ≈ 푒휆푡|훿Z0|
Krissia de Zawadzki CUDA/OpenCL 56 / 61
74. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Equa¸c˜ao diferencial com caos
GPU
CUDA version: v5050
CUDA Devices: 1
0: GeForce GTX 650: 3.0
Global memory: 2047mb
Shared memory: 48kb
Constant memory: 64kb
Block registers: 65536
Multiprocessors: 2
Max threads per multiprocessor:
2048
Warp size: 32
Threads per block: 1024
Max block dimensions: [ 1024,
1024, 64 ]
Max grid dimensions: [
2147483647, 65535, 65535 ]
Krissia de Zawadzki CUDA/OpenCL 57 / 61
75. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Equa¸c˜ao diferencial com caos
Caos - resultados
푥 e 푢 como func~ao de 푡
Krissia de Zawadzki CUDA/OpenCL 58 / 61
76. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Equa¸c˜ao diferencial com caos
Caos - resultados
Espaco de fase 푢 por 푥
Krissia de Zawadzki CUDA/OpenCL 58 / 61
77. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Equa¸c˜ao diferencial com caos
Caos - resultados
Expoente de Lyapunov
Krissia de Zawadzki CUDA/OpenCL 58 / 61
78. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Equa¸c˜ao diferencial com caos
Caos - an´alise de desempenho
Krissia de Zawadzki CUDA/OpenCL 59 / 61
79. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Equa¸c˜ao diferencial com caos
Caos - an´alise de desempenho
Krissia de Zawadzki CUDA/OpenCL 59 / 61
80. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Equa¸c˜ao diferencial com caos
Caos - an´alise de desempenho
Krissia de Zawadzki CUDA/OpenCL 59 / 61
81. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Conclus˜oes
3 Uso de GPU's e altamente recomendado em aplicac~oes com
paralelismo de dados
3 Cada vez mais aplicac~oes exigir~ao alta performance e fomentar~ao o
desenvolvimento de GPU's e de modelos de programac~ao paralelos
3 CUDA e um modelo de programac~ao inteligvel e permite explorar
e
82. cientemente o paralelismo de aplicac~oes e os recursos da GPU
3 Parallel Thinking: antes de portar um codigo para rodar na GPU e
importante reconhecer quais os trechos sequenciais e os paralelos e
explorar ao maximo este usando os recursos GPU
Krissia de Zawadzki CUDA/OpenCL 60 / 61
83. CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao
Refer^encias
3 Kirk, D. ; Hwu, W.W. Programming massively parallel processors
3 www.nvidia.com/object/gpu-applications.html
3 https://developer.nvidia.com/cuda-gpus
3 http://cs.nyu.edu/courses/spring12/CSCI-GA.3033-012/
Krissia de Zawadzki CUDA/OpenCL 61 / 61
85. Tesla vs. Fermi - Arquiteturas CUDA 6 Curiosidades
GPU Tesla: Alto paralelismo da arquitetura
Cada GPU G200b (com arquitetura Tesla) contem 30 SMs
(Streaming Multiprocessors).
Uma placa de v´ıdeo pode ter mais de uma GPU. Por exemplo, a
GTX295 possui duas dessas GPUs.
Cada um desses SMs contem 8 ALUs (Arithmetic-Logic Units).
NVidia chama ALUs de “CUDA cores”, mas esse nome ´e ilus´orio,
pois n˜ao se tratam de cores completos (com unidade de execu¸c˜ao,
etc.)
Alto throughput { e possvel requisitar para cada ALU uma
operac~ao logica ou aritmetica por ciclo.
Krissia de Zawadzki CUDA/OpenCL 2 / 13
86. Tesla vs. Fermi - Arquiteturas CUDA 6 Curiosidades
GPU Tesla: Limita¸c˜oes impostas pela arquitetura
Entretanto, cada ALU e construda na forma de um pipeline de
varios estagios, apresentando muitos ciclos de lat^encia
(da ordem de 24 ciclos).
As 8 ALUs de um SM precisam executar a mesma instruc~ao ao longo
de 4 ciclos, que e o tempo de resposta do dispatcher de instruc~oes.
Por isso, cada instru¸c˜ao precisa ser executada pelo menos um total
de 32 vezes. Isso ´e chamado de um warp.
Para superar ambas as limitac~oes, o programa deve ser organizado
de forma a executar em cada SM um numero de threads bem maior
que o numero de ALUs disponveis.
O dispatcher da Tesla precisa de pelo menos 2 warps para funcionar
de forma cont´ınua, ent˜ao o m´ınimo ´e de 64 threads para n˜ao
desperdi¸car oportunidades de inserir opera¸c˜oes nas ALUs.
Recomenda-se de 128 a 192 threads. Dessas threads, apenas 8
executam simultaneamente por vez. Ent˜ao, cada thread fica ociosa
ciclos o suficiente para compensar a lat^encia de cada opera¸c˜ao.
Krissia de Zawadzki CUDA/OpenCL 3 / 13
87. Tesla vs. Fermi - Arquiteturas CUDA 6 Curiosidades
GPU Tesla: Instru¸c˜oes condicionais
Instru¸c˜oes subsequentes a uma
compara¸c˜ao podem verificar se os
operandos eram iguais (eq),
diferentes (ne), um menor que o
outro (lt), etc.
A instru¸c˜ao s´o executa se a condi¸c˜ao
for verdadeira, caso contr´ario a ALU
fica ociosa por um ciclo.
Inspirado na arquitetura ARM.
Por´em capaz de memorizar o
resultado de at´e 4 compara¸c˜oes
($p0–$p3) em vez de somente a
´ultima realizada.
No ARM, evita esvaziar o pipeline
em pequenas condicionais dif´ıceis de
prever.
Na GPU, evita a diverg^encia de
warps.
Krissia de Zawadzki CUDA/OpenCL 4 / 13
88. Tesla vs. Fermi - Arquiteturas CUDA 6 Curiosidades
GPU Tesla: Recursos compartilhados de uma SM
Cada SM tem 16384 registradores de 32 bits que s~ao divididos
igualmente entre as threads.
O conjunto de instruc~oes e capaz de enderecar no maximo 128
registradores por thread. Porem o ultimo registrador ($r127) e
somente-escrita, apelidado de bitbucket.
Se alocarmos menos de 128 threads por SM, estaremos
desperdi¸cando registradores!
Cada SM tem 16384 bytes de memoria compartilhada. Essa
memoria e dividida em 16 bancos de memoria. Apenas enderecos
situados em bancos diferentes podem ser acessados simultamente no
mesmo ciclo.
Essa mem´oria ´e entrela¸cada. Cada 4 bytes (32 bits) adjacentes s˜ao
colocados em um banco diferente.
Se duas threads tentarem acessar simultameamente o mesmo banco,
o acesso ´e serializado pelo hardware e perde-se paralelismo.
Krissia de Zawadzki CUDA/OpenCL 5 / 13
89. Tesla vs. Fermi - Arquiteturas CUDA 6 Curiosidades
GPU Tesla: Mem´oria global
A memoria global e compartilhada entre todas as SMs e e acessvel
tambem pela CPU hospedeira.
A lat^encia de acesso e na faixa de 400 a 600 ciclos.
O throughput e de no maximo um acesso de 32 bits para cada SM
por ciclo.
Na arquitetura Tesla, n~ao existe cache. O programador deve
explicitamente copiar os dados para memorias mais locais, conforme
necessario para obter desempenho.
Krissia de Zawadzki CUDA/OpenCL 6 / 13
90. Tesla vs. Fermi - Arquiteturas CUDA 6 Curiosidades
GPU Fermi: Principais diferen¸cas
Cache para mem´oria global; mais mem´oria
compartilhada; dobro de registradores.
Qu´adruplo de ALUs em cada SM.
NVidia aumentou o poder de uma SM
em vez de aumentar muito o n´umero de
SMs, reduzindo n´umero de transistores
necess´arios para o mesmo pico de
GFLOPS.
Warps agora duram 2 ciclos e, devido `as 2
unidades de dispatch, agora ´e poss´ıvel
executar 2 warps simultaneamente em uma
SM, um em cada grupo de 16 ALUs.
Portanto, o tamanho do warp continua
sendo de 32 threads.
Melhor suporte a precis˜ao dupla.
Por´em apenas um warp por vez (metade
do throughput da precis˜ao simples).
Krissia de Zawadzki CUDA/OpenCL 7 / 13
91. Tesla vs. Fermi - Arquiteturas CUDA 6 Curiosidades
Unified memory - CUDA6
Unified memory - CUDA6
7 mem´orias da CPU e da GPU eram fisicamente distintas e separadas pelo PCI-Express bus
3 Unified memory permite `a CPU o acesso direto a dados da GPU e vice-versa
3 H´a uma managed memory que torna dads acess´ıveis para CPU e para GPU por um ´unico
ponteiro
Krissia de Zawadzki CUDA/OpenCL 8 / 13
92. Tesla vs. Fermi - Arquiteturas CUDA 6 Curiosidades
Top 500 - m´aquinas com CUDA
Top 500 - m´aquinas com CUDA
Krissia de Zawadzki CUDA/OpenCL 9 / 13
93. Tesla vs. Fermi - Arquiteturas CUDA 6 Curiosidades
Performance em aplica¸c˜oes cient´ıticas - Tesla K40
Performance em aplica¸c˜oes cient´ıticas - Tesla K40
Krissia de Zawadzki CUDA/OpenCL 10 / 13
94. Tesla vs. Fermi - Arquiteturas CUDA 6 Curiosidades
Papers Web of Science
Papers Web of Science
Krissia de Zawadzki CUDA/OpenCL 11 / 13
95. Tesla vs. Fermi - Arquiteturas CUDA 6 Curiosidades
Tend^encias de sal´ario IT
Tend^encias de sal´ario IT
Krissia de Zawadzki CUDA/OpenCL 12 / 13
96. Tesla vs. Fermi - Arquiteturas CUDA 6 Curiosidades
Tend^encias de emprego IT
Tend^encias de emprego IT
Krissia de Zawadzki CUDA/OpenCL 13 / 13