Escolar Documentos
Profissional Documentos
Cultura Documentos
START
Pipeline Grfico
- Pipeline / Estgios - Gargalo - Otimizao - Tipos de Processamento Paralelo
referncia
Dispositivos de Rasterizao
-Brinquedo de U$ 175.000,00
Programmable GPU
- Vertex and Pixel Shaders - Arquitetura orientada a estrutura de dados de computao grfica
Programmable GPU
Programmable GPU
GPGPU
- Problema de ter que mapear tudo para APIs - Usar funes OpenGL ou DirectX para efetuar todo tipo de operaes -LINGUAGEM BROOKS (Ian Buck, 2003)
Arquiteturas Unificadas
GPU
CUDA
16KB / 48KB
768KB
- Maior proximidade com C++ -Acesso a um thread especifico dentro de um cluster de GPUs - Facilidade em implementar algoritmos paralelos que requerem threads concorrentes (entre GPUs) -Host diferentes podem gerenciar threads diferentes -Gerenciamento de memria dinmica -Mtodos virtuais de C++ -Proximidade com STL do C++
- NVIDIA Performance Primitives Libraries (NPP), para processamento de imagens - GPUDirect 2.0
GPU x CPU
Paralelismo na CPU
Paralelismo na GPU
Funes em CUDA
__ global__ void KernelFunction (...) dim3 DimGrid (100, 10); // Grid com 1000 blocos dim3 DimBlock (4, 8, 8); // Cada bloco tem 256 threads
Funes em CUDA
kernel
__global__ void vecAdd(float* A, float* B, float* C) { int i = threadIdx.x; C[i] = A[i] + B[i]; } int main() { ... vecAdd<<<1, N>>>(A, B, C); }
define um ID de um dos threads numero de blocos (n) e threads (m) solicitados para o kernel
kernel
__global__ void vecAdd(float* A, float* B, float* C) { int i = threadIdx.x; C[i] = A[i] + B[i]; } int main() { vecAdd<<<1, N>>>(A, B, C); }
define um ID de um dos threads numero de blocos (n) e threads (m) solicitados para o kernel PROBLEMA - Nmero mximo de threads por bloco: 1024 - Nmero mximo de Blocos: 65.535
WARPS
Invocando o kernel
Int main (void) { int A[N], B[N], C[N]; int *dev_a, *dev_b, *dev_c; cudaMalloc ( (void **) &dev_a, N * sizeof (int) ) ); cudaMalloc ( (void **) &dev_b, N * sizeof (int) ) ); cudaMalloc ( (void **) &dev_c, N * sizeof (int) ) ); // Supondo que a e b sejam preenchidos aqui... cudaMemcpy (dev_a, A, N * sizeof(int), cudaMemcpyHostToDevice); cudaMemcpy (dev_b, B, N * sizeof(int), cudaMemcpyHostToDevice); VecAdd <<dimGrid, dimBlocos>> (dev_a, dev_b, dev_c); cudaMemcpy (C, dev_c, N * sizeof(int), cudaMemcpyHostToDevice); // Use o resultado da soma no vetor C.... CudaFree (dev_a); CudaFree (dev_b); CudaFree (dev_c); }
A memria compartilhada
Como os threads podem interagir e intercambiar dados entre si? Nada vem de graa: problema de concorrncia de dados
const int numThreadsPorBloco = 256; __global__ void dot (float *x, float *y, float *z) { __shared__ float cache [numThreadsPorBloco]; Int id = threadIdx.x + blockIdx.x * blockDim.x; Int cacheIndex = threadIdx.x; Float temp = 0; While (id < N) { Temp += x[id] * y[id]; Id += blockDim.x * gridDim.x; } cache[cacheIndex] = temp; }
Problema da Sincronizao...
(x1, x2, x3, x4) . (y1, y2, y3, y4) = x1.y1 + x2.y2 + x3.y3 + x4.y4
const int numThreadsPorBloco = 256; __global__ void dot (float *x, float *y, float *z) { __shared__ float cache [numThreadsPorBloco]; Int id = threadIdx.x + blockIdx.x * blockDim.x; Int cacheIndex = threadIdx.x; Float temp = 0; While (id < N) { Temp += x[id] * y[id]; Id += blockDim.x * gridDim.x; } cache[cacheIndex] = temp; }
Problema da Sincronizao...
// Espere todos os threads terminarem de calcular a soma __syncthreads (); int i = blockDim.x/2; While (i != 0) { If (cacheIndex < i) cache[cacheIndex] += cache[cacheIndex + i]; __syncthreads(); } If (cacheIndex == 0) c[blockIdx.x] = cache[0]; }