GPGPU
GPU
GPU – Quebra de paradigma radical Você mudaria todo o teu paradigma de desenvolvimento e hardware apenas para ganhar 5% de desempenho?
GPGPU – a evolução ... Há 3 fases históricas das GPUs: Fixed Function GPU Programmable GPU Arquitetura Unificada
Fixed Function GPUs Arquitetura incapaz de aceitar programação Impossível realizar cálculos sem ser de computação gráfica Incapacidade de acesso ao processador Conceito de APIs
Fixed Function GPUs Processador(es) CPU Back Buffer Engine de Geometria Engines de Rasterização d e v í o M e m ó r i a Front Buffer Back Buffers Interface CPU - GPU Front Buffer Z Buffer Stencil Buffer CPU Texture Buffer Interface GPU - Video
Programmable GPU Vertex and Pixel Shaders Arquitetura orientada a estrutura de dados de computação gráfica
Programmable GPU
Programmable GPU
Arquitetura Unificada - CUDA
Programmable GPU Limitações: Shaders Modo de endereçamento limitado Pequeno grupo de instruções Dificuldade de comunicação entre processadores e processos
GPGPU Problema de ter que mapear tudo para APIs Usar funções OpenGL ou DirectX para efetuar todo tipo de operações
Arquitetura Unificada - CUDA
Arquitetura Unificada - CUDA Paralelismo sem esforço, baixo custo...
Por que mais rápido? Tarefa 100 vezes mais rápido Tarefa de 1 ano de duração cai para 3 dias Tarefa de 1 dia cai para 15 minutos Tarefa de 3 segundos cai para 30 vezes por segundo
Exemplo: Simulação de Multidão
GPU Operações aritiméticas ++ Operações de memória --
Threads Porque programar em Threads? Para fazer distribuição de carga em arquitetura single core Para fazer distribuição de carga entre múltiplos núcleos Desafio de ter que manter o máximo de uso de cada núcleo
Threads Quantas threads voce já criou para seu programa?
Threads CUDA permite até 12 mil threads CUDA é basicamente um cluster de threads
Threads – Custo de gerenciamento Em CPU, como fazemos pouca troca de threads, podemos achar natural gastar 1000 instruções para fazer a troca de uma thread para outra. Em CUDA há outro paradigma.... Não é necessário gerenciar as threads, a priori. Sincronismo deve ser explicito
Modelo de Programação CUDA estende a linguagem C através de kernels Kernels equivalem a funções, que serão executadas N vezes em paralelo N é o número de threads
Arquitetura do Software
Funções em CUDA Não pode haver recursão no __device__ Sem variáveis estáticas Sem numero variável de parâmetros A chamada do kernel é assíncrona Sincronismo deve ser feito explicitamente __device__ __host__ : podem ser usados juntos
Limite de banda de memória Importância do reuso de dados
Threads, Blocos e Grids Um kernel corresponde a um grid de Blocos Cada Bloco é composto por threads Todas as threads compartilham a mesma área de memória As threads de um mesmo bloco podem compartilhar umas com as outras Threads de blocos diferentes não podem compartilhar memória entre si
Threads, Blocos e Grids - memórias
Palavras reservadas
Hierarquia de Threads Todos os threads de um bloco usam da mesma memória compartilhada. O número de threads num bloco é limitado pela memória: GPUs atuais possuem até 512 threads.
Funções em CUDA __ global__ void KernelFunction (...) dim3 DimGrid (100, 10); // Grid com 1000 blocos dim3 DimBlock (4, 8, 8); // Cada bloco tem 256 threads Size_t SharedMemBytes = 32 KernelFun << DimGrid, DimBlock, SharedMemBytes>> (...);
Kernel – será compilado para a GPU // Kernel definition __global__ void vecAdd(float* A, float* B, float* C) { } int main() // Kernel invocation vecAdd<<<1, N>>>(A, B, C); __global define que é um 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); threadIdx define um ID de um dos threads << n, m>> numero de blocos (n) e threads (m) solicitados para o kernel
Hierarquia de Threads threadIdx é um vetor de 3 componentes Threads podem ser identificados com índices de 1, 2 ou 3 dimensões (formando thread blocks de uma, duas ou três dimensões) Índice de uma thread: Se for um bloco 1D: é a mesma coisa Se for um bloco 2D (Dx, Dy): threadId de um thread de índice (x, y) é x + yDx Se for um bloco 3D (Dx, Dy, Dz): threadId de uma thread de índice (x, y, z) é x + yDx + zDxDy
Primeiro exemplo de programa cudaMalloc aloca espaço de memória global da GPU
Primeiro exemplo de programa
kernel Como faria para somar uma Matriz?
As GPUs vão desaparecer...