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
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
CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao 
CUDA - Introdu¸c˜ao 
CUDA 
Compute Uni
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
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
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
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
cada → CUDA! 
Krissia de Zawadzki CUDA/OpenCL 6 / 61
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
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
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
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
CUDA - Introdu¸c˜ao GPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao 
Aplica¸c˜oes 
Krissia de Zawadzki CUDA/OpenCL 11 / 61
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
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
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
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
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
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
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
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
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
cador da thread →  de memoria e controle 
Krissia de Zawadzki CUDA/OpenCL 18 / 61
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
cador do bloco em um grid 
Krissia de Zawadzki CUDA/OpenCL 19 / 61
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
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
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
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
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
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
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
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
gurac~oes de 
blocos e de threads 
Krissia de Zawadzki CUDA/OpenCL 24 / 61
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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

CUDA/Open CL

  • 1.
    CUDA/OpenCL Arquiteturas Avancadasde 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˜aoGPU 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˜aoGPU 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˜aoGPU 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˜aoGPU 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˜aoGPU 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˜aoGPU 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˜aoGPU 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˜aoGPU 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˜aoGPU 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˜aoGPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao Aplica¸c˜oes Krissia de Zawadzki CUDA/OpenCL 11 / 61
  • 14.
    CUDA - Introdu¸c˜aoGPU 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˜aoGPU 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˜aoGPU 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˜aoGPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao GPU CPU vs. GPU Krissia de Zawadzki CUDA/OpenCL 14 / 61
  • 18.
    CUDA - Introdu¸c˜aoGPU e CUDA Programando em CUDA OpenCL Caos Conclus˜ao GPU CPU vs. GPU Krissia de Zawadzki CUDA/OpenCL 14 / 61
  • 19.
    CUDA - Introdu¸c˜aoGPU 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˜aoGPU 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˜aoGPU 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˜aoGPU 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˜aoGPU 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 blocoem um grid Krissia de Zawadzki CUDA/OpenCL 19 / 61
  • 26.
    CUDA - Introdu¸c˜aoGPU 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˜aoGPU 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˜aoGPU 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˜aoGPU 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˜aoGPU 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˜aoGPU 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˜aoGPU 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˜aoGPU 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
  • 34.
    gurac~oes de blocose de threads Krissia de Zawadzki CUDA/OpenCL 24 / 61
  • 35.
    CUDA - Introdu¸c˜aoGPU 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˜aoGPU 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˜aoGPU 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˜aoGPU 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 diretamenteem 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 { muitasvariaveis 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˜aoGPU 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˜aoGPU 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˜aoGPU 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˜aoGPU 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˜aoGPU 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˜aoGPU 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˜aoGPU 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˜aoGPU 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˜aoGPU 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˜aoGPU 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˜aoGPU 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~aokernel 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˜aoGPU 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~aomatricial 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˜aoGPU 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˜aoGPU 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˜aoGPU 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˜aoGPU 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˜aoGPU 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 esperaate 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˜aoGPU 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˜aoGPU 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 dadosda 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˜aoGPU 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˜aoGPU 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˜aoGPU 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 dadosna 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˜aoGPU 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˜aoGPU 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˜aoGPU 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˜aoGPU 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˜aoGPU 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˜aoGPU 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˜aoGPU 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˜aoGPU 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˜aoGPU 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˜aoGPU 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˜aoGPU 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˜aoGPU 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˜aoGPU 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˜aoGPU 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 paralelismode 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˜aoGPU 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