Filipo Novo Mór
Desenvolvendo
aplicações de uso geral
para GPU com CUDA.
Mini-curso
17 de Outubro de 2016
Semana Acadêmica
Faculdade SENAC Porto Alegre
Agenda
• Conceitos básicos
• Um Pouco de História
• O que é uma GPU?
• Programação GPU CUDA
• Exemplos
• Alternativas a CUDA
• Roadmap GPUs NVIDIA
Conceitos Básicos
CPU Driven Graphics
RAMRAMRAM
CPU
CPU Driven Graphics
RAMRAMRAM
CPU Driven Graphics
CPU
video
adapter
Um Pouco de História
Um Pouco de História
• Aceleradores gráficos.
– Um “meio de campo” entre o processador e a
saída de vídeo.
• Alguns exemplos:
Um Pouco de História
• 1976: RCA Pixie (CDP1861)
– Resolução de 62x128 (RCA Studio II)
Um Pouco de História
• 1977: Television Interface Adapter (TIA) 1A
– Som, joysticks e tela
– Animação por sprites
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
Um Pouco de História
• 1982: Intel iSBX275
– Resolução 256x256 (8 cores)
– Resolução 512x512 (monocromático)
– 32MB
– DMA
Um Pouco de História
• 1984: IBM EGA (Motorola 6845)
– Resolução 640x350 (16 cores)
– Paleta de 64 cores.
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.
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).
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();
}
}
…
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. …”
Um Pouco de História
• Quake foi portado para OpenGL, mas nunca para Direct
3D da Microsoft.
Um Pouco de História
• 1995: NVIDIA lança o NV1.
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.
Um Pouco de História
Um Pouco de História
• 1999: GeForce 256 SDR - a primeira GPU
David Kirk and Wen-mei Hwu
Um Pouco de História
• 1999: GeForce 256 SDR - a primeira GPU
Grass Demo – NVIDIA Corporation, 1999
O quê é uma GPU?
Host Interface
Vertex Control
VS / T&L
Triangule Setup
Raster
Shader
Raster Operation
FBI
Vertex
Cache
Texture
Cache
Frame
Buffer
Memory
HOST
(CPU)
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
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.
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.
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.
Host Interface
Vertex Control
VS / T&L
Triangule Setup
Raster
Shader
Raster Operation
FBI
Vertex
Cache
Texture
Cache
Frame
Buffer
Memory
HOST
(CPU)
Chua Hock-Chuan, 2014
Host Interface
Vertex Control
VS / T&L
Triangule Setup
Raster
Shader
Raster Operation
FBI
Vertex
Cache
Texture
Cache
Frame
Buffer
Memory
HOST
(CPU)
 Determina a
cor final de cada
pixel.
Host Interface
Vertex Control
VS / T&L
Triangule Setup
Raster
Shader
Raster Operation
FBI
Vertex
Cache
Texture
Cache
Frame
Buffer
Memory
HOST
(CPU)
 Suaviza
(mistura) as
cores de áreas
limitrofes e
transparências.
Host Interface
Vertex Control
VS / T&L
Triangule Setup
Raster
Shader
Raster Operation
FBI
Vertex
Cache
Texture
Cache
Frame
Buffer
Memory
HOST
(CPU)
 Frame Buffer
Interface –
gerencia os
acessos a Frame
Buffer Memory.
Pipeline OpenGL simplificado
LambdaCube 3D, 2016
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.
O quê é uma GPU?
O quê é uma GPU?
Závodszky, 2014
WARP
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.
O quê é uma GPU?
Taxonomia de Flynn
Onde melhor se enquadra uma GPU?
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.
Programação GPU com CUDA
• 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
• 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
Programação GPU com CUDA
Arquitetura simplificada de uma GPU NVIDIA
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
Programação GPU com CUDA
• RDMA:
– Transferência direta entre
a GPU e outro periférico
compatível.
Alan Gray, 2013
Programação GPU com CUDA
• GPU Direct (RDMA):
– Transferência direta GPUs
NVIDIA, 2013
Programação GPU com CUDA
O mundo é das threads!
– Transferência direta GPUs
Programação GPU com CUDA
0 1 2 3 …
thread ID
4
Programação GPU com CUDA
Programação GPU com CUDA
• Memória Compartilhada 10x
mais rápida que Memória
Global.
Programação GPU com CUDA
Nitin Gupta, 2013
 Threads paralelas acessando
posições contiguas de memória =
melhor desempenho!
Branch Divergence
Programação GPU com CUDA
Branch Divergence
Programação GPU com CUDA
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
Mãos a obra!!!
Programação GPU com CUDA
Hello, World!
Programação GPU com CUDA
Código de Jason Sanders, apresentado na GTC 2010.
Hello, World!
Programação GPU com CUDA
Indica que a função será executada no device.
O compilador nvcc separará código host do código device.
Hello, World!
Programação GPU com CUDA
“<<< >>>” indica uma chamada a partir do host a uma função device (kernel).
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.
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().
Programação GPU com CUDA
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.
Soma de Vetores
Programação GPU com CUDA
c[0] = a[0] + b[0];
Bloco 0
c[1] = a[1] + b[1];
Bloco 1
c[2] = a[2] + b[2];
Bloco 2
c[3] = a[3] + b[3];
Bloco 3
Programação GPU com CUDA
Programação GPU com CUDA
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.
Trabalhando com Threads.
Programação GPU com CUDA
• um Kernel CUDA pode ser executado em vários
blocos de threads.
Trabalhando com Threads.
Programação GPU com CUDA
Trabalhando com Threads e Blocos!
Programação GPU com CUDA
blockIdx.x = 2
blockDim.x = 6
threadIdx.x = 2
2 * 6 + 2
14
Trabalhando com Threads e Blocos!
Programação GPU com CUDA
Programação GPU com CUDA
Programação GPU com CUDA
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!
Produto Escalar Vetorial
Programação GPU com CUDA
𝑐 = 𝑎 ∙ 𝑏
𝑐 = 𝑎0, 𝑎1, 𝑎2, 𝑎3, 𝑎4 ∙ 𝑏0, 𝑏1, 𝑏2, 𝑏3, 𝑏4
𝑐 = 𝑎0 𝑏0 + 𝑎1 𝑏1 + 𝑎2 𝑏2 + 𝑎3 𝑏3 + 𝑎4 𝑏4
Produto Escalar Vetorial
Programação GPU com CUDA
GPU Programming
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.
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
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.
Implementação Serial Tradicional
NAIVE!
• Claramente N2
• Cada par de partículas é calculado duas vezes.
• Aceleração deve ser ajustada ao final.
Implementação Serial Tradicional
• Segue sob domínio N2 , mas:
• Cada par é comparado apenas uma vez.
• Aceleração está OK ao final!
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.
Análise
“naive” Serial
𝑛2
“smart” Serial
𝑛2
− 𝑛
2
for (i=0; i<N; i++)
{
for(j=i+1; j<N; j++)
{
printf(“*”);
}
printf(“n”);
}
*****
*****
*****
*****
*****
≈ 𝒏
𝒏 − 𝟏
𝟐
OpenMP Parallel
𝑛2
𝑝
Implementação CUDA
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
Global Memory
Shared
Memory
Bank
N = 15
K = 3
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
BARRIER
Global Memory
Shared
Memory
Bank
Active Tasks
Active Transfers
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
0 1 2
Global Memory
Shared
Memory
Bank
Active Tasks
Active Transfers
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
BARRIER
Global Memory
Shared
Memory
Bank
Active Tasks
Active Transfers
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
3 4 5
Global Memory
Shared
Memory
Bank
Active Tasks
Active Transfers 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
BARRIER
Global Memory
Shared
Memory
Bank
Active Tasks
Active Transfers
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
6 7 8
Global Memory
Shared
Memory
Bank
Active Tasks
Active Transfers 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
BARRIER
Global Memory
Shared
Memory
Bank
Active Tasks
Active Transfers
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
9 10 11
Global Memory
Shared
Memory
Bank
Active Tasks
Active Transfers 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
BARRIER
Global Memory
Shared
Memory
Bank
Active Tasks
Active Transfers
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
12 13 14
Global Memory
Shared
Memory
Bank
Active Tasks
Active Transfers 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
Global Memory
Shared
Memory
Bank
Active Tasks
Active Transfers
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
Global Memory
Shared
Memory
Bank
Implementação CUDA
Cálculo da força entre duas
partículas.
Implementação CUDA
Kernel.
Implementação CUDA
Kernel.
Implementação CUDA
Trecho do código host.
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.
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
Resultados Experimentais
Resultados Experimentais
Resultados Experimentais
Resultados Experimentais
Alternativas
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 ?
Alternativas
• OpenACC (multiplicação de matrizes)
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.
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.
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
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.
Alternativas
• OpenMP 4.0
OpenMP 4.0 para GPU NVIDIA
OpenACC para GPU NVIDIA
NVIDIA Roadmap
Muito obrigado!
Dúvidas? Comentários?
Filipo Novo Mór
www.filipomor.com

Desenvolvendo Aplicações de Uso Geral para GPU com CUDA

  • 1.
    Filipo Novo Mór Desenvolvendo aplicaçõesde uso geral para GPU com CUDA. Mini-curso 17 de Outubro de 2016 Semana Acadêmica Faculdade SENAC Porto Alegre
  • 2.
    Agenda • Conceitos básicos •Um Pouco de História • O que é uma GPU? • Programação GPU CUDA • Exemplos • Alternativas a CUDA • Roadmap GPUs NVIDIA
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
    Um Pouco deHistória
  • 8.
    Um Pouco deHistória • Aceleradores gráficos. – Um “meio de campo” entre o processador e a saída de vídeo. • Alguns exemplos:
  • 9.
    Um Pouco deHistória • 1976: RCA Pixie (CDP1861) – Resolução de 62x128 (RCA Studio II)
  • 10.
    Um Pouco deHistória • 1977: Television Interface Adapter (TIA) 1A – Som, joysticks e tela – Animação por sprites
  • 11.
    Um Pouco deHistória • 1978: Motorola MC6845 – Monochrome and Color Display Adapter (MDA/CDA) – Base para IBM PC (1981) , Apple II e Tandy CoCo
  • 12.
    Um Pouco deHistória • 1982: Intel iSBX275 – Resolução 256x256 (8 cores) – Resolução 512x512 (monocromático) – 32MB – DMA
  • 13.
    Um Pouco deHistória • 1984: IBM EGA (Motorola 6845) – Resolução 640x350 (16 cores) – Paleta de 64 cores.
  • 14.
    Um Pouco deHistó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 deHistó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 deHistó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 deHistó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 deHistória • Quake foi portado para OpenGL, mas nunca para Direct 3D da Microsoft.
  • 19.
    Um Pouco deHistória • 1995: NVIDIA lança o NV1.
  • 20.
    Um Pouco deHistó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.
  • 21.
    Um Pouco deHistória
  • 22.
    Um Pouco deHistória • 1999: GeForce 256 SDR - a primeira GPU David Kirk and Wen-mei Hwu
  • 23.
    Um Pouco deHistória • 1999: GeForce 256 SDR - a primeira GPU Grass Demo – NVIDIA Corporation, 1999
  • 24.
    O quê éuma GPU?
  • 25.
    Host Interface Vertex Control VS/ T&L Triangule Setup Raster Shader Raster Operation FBI Vertex Cache Texture Cache Frame Buffer Memory HOST (CPU)
  • 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.
  • 30.
    Host Interface Vertex Control VS/ T&L Triangule Setup Raster Shader Raster Operation FBI Vertex Cache Texture Cache Frame Buffer Memory HOST (CPU) Chua Hock-Chuan, 2014
  • 31.
    Host Interface Vertex Control VS/ T&L Triangule Setup Raster Shader Raster Operation FBI Vertex Cache Texture Cache Frame Buffer Memory HOST (CPU)  Determina a cor final de cada pixel.
  • 32.
    Host Interface Vertex Control VS/ T&L Triangule Setup Raster Shader Raster Operation FBI Vertex Cache Texture Cache Frame Buffer Memory HOST (CPU)  Suaviza (mistura) as cores de áreas limitrofes e transparências.
  • 33.
    Host Interface Vertex Control VS/ T&L Triangule Setup Raster Shader Raster Operation FBI Vertex Cache Texture Cache Frame Buffer Memory HOST (CPU)  Frame Buffer Interface – gerencia os acessos a Frame Buffer Memory.
  • 34.
  • 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.
  • 36.
    O quê éuma GPU?
  • 37.
    O quê éuma GPU? Závodszky, 2014 WARP
  • 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.
  • 41.
  • 42.
    • Utilizar opoderde 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 oCUDA: – 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
  • 44.
    Programação GPU comCUDA Arquitetura simplificada de uma GPU NVIDIA
  • 45.
    Programação GPU comCUDA • 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 comCUDA • RDMA: – Transferência direta entre a GPU e outro periférico compatível. Alan Gray, 2013
  • 47.
    Programação GPU comCUDA • GPU Direct (RDMA): – Transferência direta GPUs NVIDIA, 2013
  • 48.
    Programação GPU comCUDA O mundo é das threads! – Transferência direta GPUs
  • 49.
    Programação GPU comCUDA 0 1 2 3 … thread ID 4
  • 50.
  • 51.
    Programação GPU comCUDA • Memória Compartilhada 10x mais rápida que Memória Global.
  • 52.
    Programação GPU comCUDA Nitin Gupta, 2013  Threads paralelas acessando posições contiguas de memória = melhor desempenho!
  • 53.
  • 54.
  • 55.
    Os Desafios-Chave naProgramaçã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
  • 56.
  • 57.
    Hello, World! Programação GPUcom CUDA Código de Jason Sanders, apresentado na GTC 2010.
  • 58.
    Hello, World! Programação GPUcom CUDA Indica que a função será executada no device. O compilador nvcc separará código host do código device.
  • 59.
    Hello, World! Programação GPUcom CUDA “<<< >>>” indica uma chamada a partir do host a uma função device (kernel).
  • 60.
    Indo um poucoadiante... 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 poucoadiante... 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().
  • 62.
  • 63.
    Indo um poucoadiante... 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.
  • 64.
    Soma de Vetores ProgramaçãoGPU com CUDA c[0] = a[0] + b[0]; Bloco 0 c[1] = a[1] + b[1]; Bloco 1 c[2] = a[2] + b[2]; Bloco 2 c[3] = a[3] + b[3]; Bloco 3
  • 65.
  • 66.
  • 67.
    Programação GPU comCUDA • 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.
  • 68.
    Trabalhando com Threads. ProgramaçãoGPU com CUDA • um Kernel CUDA pode ser executado em vários blocos de threads.
  • 69.
  • 70.
    Trabalhando com Threadse Blocos! Programação GPU com CUDA blockIdx.x = 2 blockDim.x = 6 threadIdx.x = 2 2 * 6 + 2 14
  • 71.
    Trabalhando com Threadse Blocos! Programação GPU com CUDA
  • 72.
  • 73.
  • 74.
    Programação GPU comCUDA • 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!
  • 75.
    Produto Escalar Vetorial ProgramaçãoGPU com CUDA 𝑐 = 𝑎 ∙ 𝑏 𝑐 = 𝑎0, 𝑎1, 𝑎2, 𝑎3, 𝑎4 ∙ 𝑏0, 𝑏1, 𝑏2, 𝑏3, 𝑏4 𝑐 = 𝑎0 𝑏0 + 𝑎1 𝑏1 + 𝑎2 𝑏2 + 𝑎3 𝑏3 + 𝑎4 𝑏4
  • 76.
  • 77.
  • 79.
    Sincronismo e Comunicaçãoentre 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.
  • 83.
    Um estudo decaso 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 Problemade 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.
  • 85.
    Implementação Serial Tradicional NAIVE! •Claramente N2 • Cada par de partículas é calculado duas vezes. • Aceleração deve ser ajustada ao final.
  • 86.
    Implementação Serial Tradicional •Segue sob domínio N2 , mas: • Cada par é comparado apenas uma vez. • Aceleração está OK ao final!
  • 87.
    Implementação OpenMP • Devese 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.
  • 88.
    Análise “naive” Serial 𝑛2 “smart” Serial 𝑛2 −𝑛 2 for (i=0; i<N; i++) { for(j=i+1; j<N; j++) { printf(“*”); } printf(“n”); } ***** ***** ***** ***** ***** ≈ 𝒏 𝒏 − 𝟏 𝟐 OpenMP Parallel 𝑛2 𝑝
  • 89.
  • 90.
    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 0 1 23 4 5 6 7 8 9 10 11 12 13 14 Global Memory Shared Memory Bank N = 15 K = 3
  • 91.
    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 0 1 23 4 5 6 7 8 9 10 11 12 13 14 BARRIER Global Memory Shared Memory Bank Active Tasks Active Transfers
  • 92.
    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 0 1 23 4 5 6 7 8 9 10 11 12 13 14 0 1 2 Global Memory Shared Memory Bank Active Tasks Active Transfers
  • 93.
    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 0 1 23 4 5 6 7 8 9 10 11 12 13 14 BARRIER Global Memory Shared Memory Bank Active Tasks Active Transfers
  • 94.
    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 3 4 5 GlobalMemory Shared Memory Bank Active Tasks Active Transfers 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
  • 95.
    0 1 23 4 5 6 7 8 9 10 11 12 13 14 BARRIER Global Memory Shared Memory Bank Active Tasks Active Transfers 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
  • 96.
    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 6 7 8 GlobalMemory Shared Memory Bank Active Tasks Active Transfers 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
  • 97.
    0 1 23 4 5 6 7 8 9 10 11 12 13 14 BARRIER Global Memory Shared Memory Bank Active Tasks Active Transfers 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
  • 98.
    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 9 10 11 GlobalMemory Shared Memory Bank Active Tasks Active Transfers 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
  • 99.
    0 1 23 4 5 6 7 8 9 10 11 12 13 14 BARRIER Global Memory Shared Memory Bank Active Tasks Active Transfers 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
  • 100.
    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 12 13 14 GlobalMemory Shared Memory Bank Active Tasks Active Transfers 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
  • 101.
    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 0 1 23 4 5 6 7 8 9 10 11 12 13 14 Global Memory Shared Memory Bank Active Tasks Active Transfers
  • 102.
    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 0 1 23 4 5 6 7 8 9 10 11 12 13 14 Global Memory Shared Memory Bank
  • 103.
    Implementação CUDA Cálculo daforça entre duas partículas.
  • 104.
  • 105.
  • 106.
  • 107.
    Análise C : custoda 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
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 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 ?
  • 115.
  • 116.
    Alternativas • OpenACC (multiplicaçãode 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çãode 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çãode 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 Deacordo 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.
  • 120.
    Alternativas • OpenMP 4.0 OpenMP4.0 para GPU NVIDIA OpenACC para GPU NVIDIA
  • 121.
  • 122.