Escolar Documentos
Profissional Documentos
Cultura Documentos
CUDA
1 / 23
CUDA
2 / 23
Outline
Kernel CUDA Qualicadores CUDA Organizao dos Threads Kernel, Congurao e Execuo Calcular o nmero correcto de threads Modelo de Execuo Sistema de Memria Global Memory 1o Programa em CUDA: Soma de dois vectores Sincronizao Gesto do Device
3 / 23
Kernel CUDA
Qualicadores CUDA
Executado no: __device__ float DeviceFunc() __global__ void __host__ KernelFunc() device device host
float HostFunc()
__device__ dene uma funo que pode ser chamada dentro do kernel ou por outra funo device
__device__ e __host__ podem ser usados em conjunto, o compilador gera duas verses de cdigo)
O default todas as funes de um programa CUDA serem funes host (quando nenhum qualicador usado)
N. Cardoso & P. Bicudo Programao em Paralelo: CUDA 4 / 23
31
Kernel CUDA
Organizao dos Threads
Host
Device Grid 1
cdigo executado no GPU (device); executado por um array de threads paralelos; todos os threads correm o mesmo cdigo os lanamentos so hierrquicas:
threads so agrupados em blocos; blocos so agrupados em grids.
Kernel 2 Block (1, 1) Kernel 1
Grid 2
inclui variveis de identicao para threads e blocos. apenas os threads dentro de um determinado bloco podem sincronizar e comunicar atravs da memria partilhada, shared memory, __syncthreads();.
Thread Thread Thread Thread (0,0,0) (1,0,0) (2,0,0) (3,0,0) Thread Thread Thread Thread (0,1,0) (1,1,0) (2,1,0) (3,1,0)
Nuno Cardoso
Courtesy:
5 / 23
Kernel CUDA
Organizao dos Threads
IDs e dimenses:
threads podem ter 3D IDs, nicos no mesmo bloco (threadIdx.x, threadIdx.y, threadIdx.z);
n mximo de threads num bloco varia dependendo da arquitectura.
o
Host
Device Grid 1
Kernel 1
blocos podem ter 2D IDs ou 3D dependendo da arquitectura e da verso do CUDA, nicos na mesma grid (blockIdx.x, blockIdx.y, blockIdx.z); Inclui ainda as dimenses do bloco, (blockDim.x, blockDim.y, blockDim.z), e dimenses da grid (gridDim.x, gridDim.y, , gridDim.z). dimenses so denidas pelo utilizador/programador aquando do lanamento do kernel; Para obter as dimenses suportadas pelo vosso GPU: ./deviceQuery "/NVIDIA_GPU_Computing_SDK/C/bin/linux/release"
Thread Thread Thread Thread (0,0,0) (1,0,0) (2,0,0) (3,0,0) Thread Thread Thread Thread (0,1,0) (1,1,0) (2,1,0) (3,1,0)
Nuno Cardoso
6 / 23
Kernel CUDA
Execution conguration
uma funo kernel deve ser chamada da seguinte forma: __global__ void KernelFunc ( . . . ) ; dim3 DimGrid ( 1 0 0 , 5 0 ) ; / / 5000 t h r e a d b l o c k s dim3 DimBlock ( 4 , 8 , 8 ) ; / / 256 t h r e a d s per b l o c k s i z e _ t SharedMemBytes = 6 4 ; / / 64 b y t e s o f shared memory KernelFunc <<< DimGrid , DimBlock , SharedMemBytes > > > ( . . . ) ;
Thread Block 1
1 2 3 4 5 6 7
Thread Block N - 1
0 1 2 3 4 5 6 7
David Kirk/NVIDIA and Wen-mei W. Hwu, 2007-2010 ECE 498AL, University of Illinois, Urbana-Champaign
22
8 / 23
tamanho do bloco: 8 8
64 threads por bloco 8 64 = 512 threads 50% de ocupao do SM.
d_P
blockDim.y
blockIdx.y
tamanho do bloco: 16 16
256 threads por bloco 1024/256 = 4 4 blocos por SM.
19 threadIdx.y
tamanho do bloco: 32 32
1024 threads por bloco > 512 excede a capacidade do SM.
X e ed de f
9 / 23
Modelo de Execuo
Threads so executados por "thread processors"
o residir num nico SM -on limitado pelos recursos do SM tais como shared memory e registos
' High-level programming interface ' No knowledge on Computer Graphics is required ' Examples: NVIDIAs CUDA, OpenCL !" # $ %
So fornecidas funes para alocar/inicializar/copiar memria no GPU No possvel distinguir se um ponteiro do CPU ou do GPU simplesmente inspecionando o seu valor. How does it work? necessrio ter muito cuidado quando se usam os ponteiros
d 69oo )p70@9@q)8
CPU
r 63@ 018
GPU
PC Memory
n 6)7k 3(0o@
GPU Memory
Cache L1 e L2:
apenas disponvel na arquitectura Fermi e Kepler.
Shared memory:
por bloco; partilhada por threads no mesmo bloco; comunicao entre threads.
Texture memory:
est "ligada" global memory; permite ser usada como cache; no pode ser escrita por threads, apenas acessvel para leitura; actualizada entre chamadas de kernels.
Thread Local Memory Block Shared Memory
Global memory:
por aplicao; partilhada por todos os threads; comunicao inter-Grid.
Constant memory:
lida e escrita pelo CPU; acessvel a qualquer thread apenas para leitura.
Grid 0
por thread por bloco por grid por grid por grid
Global Memory
12 / 23
Agrupar transferncias
Uma grande transferncia muito melhor do que muitas pequenas
13 / 23
Host
Global Memory
cudaMemcpy()
requer 4 parmetros
ponteiro de destino ponteiro da fonte nmero de bytes para copiar tipo de transferncia:
Host to Host cudaMemcpyHostToHost Host to Device cudaMemcpyHostToDevice Device to Host cudaMemcpyDeviceToHost Device to Device cudaMemcpyDeviceToDevice
Exemplo:
cudaMemcpy ( array_d , array_h , s i z e o f ( f l o a t ) N, cudaMemcpyHostToDevice ) ; cudaMemcpy ( array_h , array_d , s i z e o f ( f l o a t ) N, cudaMemcpyDeviceToHost ) ;
15 / 23
1o Programa em CUDA
Exemplo: Soma de dois vectores
CPU
r 63@ 018
GPU
Implementao:
1 2 3 4
Criar 3 arrays no host; Inicializar os 3 arrays no host; Criar 3 arrays no device; Copiar os 3 arrays do host para o device; Chamar o kernel; Copiar os 3 arrays do device para o host; Vericar resultado; Libertar os recursos.
PC Memory
n 6)7k 3(0o@
GPU Memory
!" # $ % j6)7k l870@ m9@9 d 69oo 3183o qp3 r 63@ 018 n 6)7k 3(0o@
5 6
7 8
16 / 23
/ / Includes # include < s t d i o . h> # include < c u t i l _ i n l i n e . h> / / Functions void RandomInit ( f l o a t , i n t ) ; void VectorAdd ( ) ; / / Device code __global__ void VecAdd ( const f l o a t A , const f l o a t B , f l o a t C, i n t N ) ; / / Host code i n t main ( i n t argc , char argv ) { p r i n t f ( " Vector a d d i t i o n \ n " ) ; VectorAdd ( ) ; exit (0); } / / F i l l an a r r a y w i t h random f l o a t e n t r i e s . void RandomInit ( f l o a t data , i n t n ) { f o r ( i n t i = 0 ; i < n ; ++ i ) data [ i ] = rand ( ) / ( f l o a t )RAND_MAX; }
17 / 23
void VectorAdd ( ) { i n t N = 50000; siz e_t size = N sizeof ( f l o a t ) ; / / Host a r r a y s f l o a t h_A , h_B , h_C ; / / Device a r r a y s f l o a t d_A , d_B , d_C ; / / Allocate input vectors h_A = ( f l o a t ) m a l l o c ( s i z e h_B = ( f l o a t ) m a l l o c ( s i z e h_C = ( f l o a t ) m a l l o c ( s i z e h_A , h_B and h_C i n h o s t memory ); ); );
/ / I n i t i a l i z e input vectors RandomInit ( h_A , N ) ; RandomInit ( h_B , N ) ; / / A l l o c a t e v e c t o r s i n d e v i c e memory c u t i l S a f e C a l l ( cudaMalloc ( ( void )&d_A , s i z e ) ) ; c u t i l S a f e C a l l ( cudaMalloc ( ( void )&d_B , s i z e ) ) ; c u t i l S a f e C a l l ( cudaMalloc ( ( void )&d_C , s i z e ) ) ; / / Copy v e c t o r s from h o s t memory t o d e v i c e memory c u t i l S a f e C a l l ( cudaMemcpy ( d_A , h_A , s i z e , cudaMemcpyHostToDevice ) ) ; c u t i l S a f e C a l l ( cudaMemcpy ( d_B , h_B , s i z e , cudaMemcpyHostToDevice ) ) ; (...)
18 / 23
20 / 23
21 / 23
Sincronizao em CUDA CUDA permite threads do mesmo bloco sincronizarem suas aces usando: __syncthreads()
Quando uma thread chama essa funo, ela bloqueada at todos os threads do bloco executarem a mesma chamada "Sincronizao por barreira" um mtodo simples e usual de coordenar atividades paralelas A opo CUDA de no permitir que threads em blocos distintos executem sincronizao por barreira, possibilita a execuo dos blocos em qualquer ordem: nenhum deles precisa esperar pelo outro!
Sincronizao no Host
Todos os lanamentos de Kernel so assncronos:
o controlo retorna para o CPU imediatamente, o kernel executado quando todas as chamadas anteriores forem completadas
cudaMemcpy sncrono
retorna o controlo para o CPU apenas aquando do cpia completa a cpia comea quando todas as chamadas anteriores estiverem completas
cudaThreadSynchronize()
bloqueia at todas as chamadas CUDA anteriores estiverem completas
N. Cardoso & P. Bicudo Programao em Paralelo: CUDA 22 / 23
Gesto do Device
Gesto da memria
cudaMalloc() cudaFree() cudaMemcpy() (...)
23 / 23