O documento apresenta um mini-curso sobre desenvolvimento de aplicações para GPU usando CUDA. A agenda inclui conceitos básicos sobre GPUs, uma breve história, programação CUDA e um estudo de caso comparativo entre CPU, OpenMP e CUDA para o problema de N-corpos.
8. Um Pouco de História
• Aceleradores gráficos.
– Um “meio de campo” entre o processador e a
saída de vídeo.
• Alguns exemplos:
9. Um Pouco de História
• 1976: RCA Pixie (CDP1861)
– Resolução de 62x128 (RCA Studio II)
10. Um Pouco de História
• 1977: Television Interface Adapter (TIA) 1A
– Som, joysticks e tela
– Animação por sprites
11. Um Pouco de História
• 1978: Motorola MC6845
– Monochrome and Color Display Adapter
(MDA/CDA)
– Base para IBM PC (1981) , Apple II e Tandy CoCo
12. Um Pouco de História
• 1982: Intel iSBX275
– Resolução 256x256 (8 cores)
– Resolução 512x512 (monocromático)
– 32MB
– DMA
13. Um Pouco de História
• 1984: IBM EGA (Motorola 6845)
– Resolução 640x350 (16 cores)
– Paleta de 64 cores.
14. Um Pouco de História
• 1985: Fundação da Array Technology Inc (ATI) no
Canadá por 3 imigrantes de Hong Kong.
• Principais contribuições:
– Color Emulation Card (16kb)
– Consórcio VESA (Video Electronics Standards
Association)
– Série EGA Wonder (que levou ao VGA Wonder).
– Série Rage (primeira com aceleração 3D)
– Família Radeon
• Comprada pela AMD em 2006.
15. Um Pouco de História
• 1992: Silicon Graphics Inc (SGI) lança o
OpenGL 1.0, a partir da sua API proprietária
IRIS GL (Integrated Raster Imaging System
Graphical Library).
16. Um Pouco de História
…
void drawBox(void)
{
int i;
for (i = 0; i < 6; i++) {
glBegin(GL_QUADS);
glNormal3fv(&n[i][0]);
glVertex3fv(&v[faces[i][0]][0]);
glVertex3fv(&v[faces[i][1]][0]);
glVertex3fv(&v[faces[i][2]][0]);
glVertex3fv(&v[faces[i][3]][0]);
glEnd();
}
}
…
17. Um Pouco de História
• Ao mesmo tempo, a Microsoft trabalhava na sua
API gráfica, Direct3D.
• John Carmack da ID Software (DOOM e Quake)
criticou abertament a API 3D da MS.
“…Direct-3D IM is a horribly broken API. It inflicts great
pain and suffering on the programmers using it,
without returning any significant advantages. I don't
think there is ANY market segment that D3D is
apropriate for, OpenGL seems to work just fine for
everything from quake to softimage. …”
18. Um Pouco de História
• Quake foi portado para OpenGL, mas nunca para Direct
3D da Microsoft.
19. Um Pouco de História
• 1995: NVIDIA lança o NV1.
20. Um Pouco de História
• NVIDIA NV1 :
– Quadratic Texture Mapping – QTM
– DirectX foi lançado logo após o lançamento da
placa, porém, usando rasterização por triangulos.
– NVIDIA somente
abandonou QTM no chip
NV3.
26. Host Interface
Vertex Control
VS / T&L
Triangule Setup
Raster
Shader
Raster Operation
FBI
Vertex
Cache
Texture
Cache
Frame
Buffer
Memory
HOST
(CPU) Recebe
comandos e
dados da CPU
27. Host Interface
Vertex Control
VS / T&L
Triangule Setup
Raster
Shader
Raster Operation
FBI
Vertex
Cache
Texture
Cache
Frame
Buffer
Memory
HOST
(CPU)
Recebe
informação no
formato de
triângulos;
Converte para
formato inteligível
pelo hardware;
Armazena essa
informação na
cache.
28. Host Interface
Vertex Control
VS / T&L
Triangule Setup
Raster
Shader
Raster Operation
FBI
Vertex
Cache
Texture
Cache
Frame
Buffer
Memory
HOST
(CPU)
Vertex Shading
Transform and
Lighting
Define e
posiciona os pixels
em coordenadas
2D a partir dos
objetos 3D.
29. Host Interface
Vertex Control
VS / T&L
Triangule Setup
Raster
Shader
Raster Operation
FBI
Vertex
Cache
Texture
Cache
Frame
Buffer
Memory
HOST
(CPU)
Define os
pixels nas
regiões onde
dois triângulos
se encontram.
35. O quê é uma GPU?
• Mas em 2006 a NVIDIA lançou uma nova
arquitetura, a GeForce 8800, com uma nova
estrutura.
• Conjuntos de Processadores organizados em
arrays.
38. O quê é uma GPU?
Mohamed Zahran
Quando blocos de threads são atribuídos a um
multiprocessador, ele é dividido em unidades básicas de
execução chamados WARPs.
39. O quê é uma GPU?
Taxonomia de Flynn
Onde melhor se enquadra uma GPU?
40. O quê é uma GPU?
SIMT vs SIMD
• Single Instruction, Multiple Register Sets: cada thread possui seu próprio
conjunto de registradores, consequentemente, instruções podem processar
dados diferentes em diferentes threads com execução simultânea.
• Single Instruction, Multiple Addresses: cada thread pode realizar acessos a
posições não contiguas da memória, dando assim maior flexibilidade ao
programador. No entanto, esta é uma técnica insegura pois este tipo de
acesso pode levar a perda de desempenho em função da serialização dos
acessos a memória.
• Single Instruction, Multiple Flow Paths: o controle de fluxo de diferentes
threads paralelas pode divergir.
42. • Utilizar opoder de processamento dos aceleradores
gráficos para aplicações que não fossem gráficas era
muito difícil!
– Instruções e estruturas de dados deveriam se basear em
primitivas gráficas, tais como triângulos ou políginos.
• Mas a NVIDIA lançou CUDA em 2007.
Compute Unified Device Architecture
GPGPU
Programação GPU com CUDA
43. • Sobre o CUDA:
– Permite que porções do código da aplicação sejam
executados diretamente na GPU.
• Extendendo a linguagem
hospedeira:
– C, C++, FORTRAN, etc.
• Utilizando comandos C-like.
• Exige grande conhecimento
sobre a arquitetura do
hardware.
Programação GPU com CUDA
45. Programação GPU com CUDA
• Transferência de dados entre CPU e GPU:
– Barramento PCI Express.
• Transferência de dados entre GPU e GPU:
– SLI (GeForce): não disponível em CUDA.
– GPU Direct
– RDMA.
Alan Gray, 2013
46. Programação GPU com CUDA
• RDMA:
– Transferência direta entre
a GPU e outro periférico
compatível.
Alan Gray, 2013
47. Programação GPU com CUDA
• GPU Direct (RDMA):
– Transferência direta GPUs
NVIDIA, 2013
55. Os Desafios-Chave na Programação para GPUs
• Transferência de dados entre CPU e GPU.
• Acesso a memória.
• Branch divergence.
• Não existência de
Recursão.
Programação GPU com CUDA
60. Indo um pouco adiante...
Programação GPU com CUDA
“add” será disparado pelo host e executado no device.
Então, a, b e c devem apontar para a memória da GPU.
61. Indo um pouco adiante...
Programação GPU com CUDA
• Ponteiros no código device apontam para memória da GPU:
• Podem ser passados a partir do host e para o host.
• O host não pode acessar a memória da GPU!
• Ponteiros no código host apontam para memória da CPU:
• Podem ser passados a partir do device e para o device.
• O device não pode acessar a memória da CPU!
• cudaMalloc(), cudaFree(), cudaMemcpy()
• Similares a malloc(), free(), memcpy().
63. Indo um pouco adiante...
Programação GPU com CUDA
• O código foi executado na GPU, mas… onde está o
paralelismo???
• Vamos tornar nosso exemplo um pouco mais
complexo: Soma de Vetores.
67. Programação GPU com CUDA
• Revisão!
– Host = CPU
– Device = GPU
– __global__para declarar uma função device.
– Passagem de parâmetros entre host e device.
– Gerenciamento de memória básico:
• cudaMalloc()
• cudaMemcpy()
• cudaFree()
– Disparando kernels no device:
• N cópias da função “add”
• Utilizando blockIdx.x para identificar o índice do
bloco de threads.
74. Programação GPU com CUDA
• Revisão!
– Qual a vantagem de se utilizar threads?
• Ao contrário dos blocos, threads possuem mecanismos
para comunicação e sincronização.
– Porque threads e blocos?
• Ocupação da GPU!
79. Sincronismo e Comunicação entre Threads:
Programação GPU com CUDA
• __syncthreads()promove um encontro entre todas
as threads do bloco.
• No exemplo mostrado, evita uma condição de
corrida.
80.
81.
82.
83. Um estudo de caso comparativo entre plataformas.
Problema de N-Corpos
Implementação serial tradicional.
Implementação OpenMP
Implementação CUDA.
Programação GPU com CUDA
84. Sobre o Problema de N-Corpos
Características:
Cálculo da força entre todas as partículas.
Complexidade O(N2)
Energia no sistema deve ser constante.
O algoritmo de cálculo das forças demanda
grande poder computacional com o
crescimento de N.
87. Implementação OpenMP
• Deve se basear na versão “naive”.
• Perdemos o “/2”, mas ganhamos o “/p”!
• OBS: agendamento estático parece ser muito mais rápido para este tipo de
aplicação.
107. Análise
C : custo da função CalculateForce.
M : custo da transferência entre as
memórias Global e Compartilhada.
T : custo da transfer6encia entre as
memórias da CPU e GPU.
Acesso a memória Compartilhada
tende a ser até 100x mais rápido
do que à memória Global.
𝑪
𝒏 𝟐
𝒑
+ 𝟐𝑴𝒏 + 𝟐𝑻𝒏
Inicialmente, todos os elementos são
transferidos da memória do Host para a memória
do Device.
Cada thread é responsável por apenas uma
partícula.
Existem (n/k) barreiras durante as sincronizações
entre as memórias Compartilhada e Global.
A cada barreira, k elementos são transferidos
para a memória Compartilhada por vez.
Ao final, todos os elementos constantes na
memória Global são copiados de volta para a
memória do Host.
108. Resultados Experimentais
Testing Environment:
Dell PowerEdge R610
2 Intel Xeon Quad-Core E5520 2.27 GHz Hyper-Threading
8 physical cores, 16 threads.
RAM 16GB
NVIDIA Tesla S2050
Ubuntu Server 10.0.4 LTS
GCC 4.4.3
CUDA 5.0
How much would it cost???
Version Cost
Naive 0.49$
Smart 0.33$
OMP 0.08$
CUDA 0.05$
Amazon EC2:
General Purpose - m1.large plan
GPU Instances - g2.2xlarge plan
114. Alternativas
• OpenACC
Allinea
CRAY Inc
Edinburgh Parallel Computing Center
Georgia Tech
University of Houston
Indiana University
NVIDIA
Oak Ridge National Lab
The Portland Group Inc (PGI)
Rogue Wave
Sandia National Laboratory
Swiss National Supercomputer Center
Technical Universitat Dresden
Tokyo Institute of Technology (TiTech)
Utilização de diretivas (pragmas) para orientação do compilador, ao estilo OpenMP.
Promessa: rápida paralelização de código legado.
Concorrência: OpenMP 4.0 ?
116. Alternativas
• OpenACC (multiplicação de matrizes)
Aloca espaço na memória do
device para os vetores A e B,
antes da execução do kernel.
Copia os vetores A e B da
memória do Host para a
memória do Device, antes da
execução do kernel.
117. Alternativas
• OpenACC (multiplicação de matrizes)
Aloca memória para o vetor C
na memória do device, antes da
execução do kernel.
Após a execução do kernel,
copia os dados do vetor C da
memória do device para a
memória do host.
118. Alternativas
• OpenACC (multiplicação de matrizes)
Blocos com 16 threads cada.
Quantidade de blocos definida
pela compilador.
pgcc -Minfo=all -ta=nvidia:5.0,cc2x,time -acc -Minfo=accel -lm mmACC_v1_1.c -o mmACC11
119. Alternativas
• OpenMP 4.0
De acordo com o site da OpenMP, um esforço contínuo está sendo feito no sentido
de unificar as plataformas. Neste contexto, aplicações OpenACC podem ser
consideradas como beta testes de OpenMP 4.0.