Paralelização com
OpenMP - CUDA
FIT - Metrocamp 2016
FIT- Metrocamp 2016 2
Agenda
● Apresentação
● Introdução
● Motivação
● OpenMP
● CUDA
● Otimização
● Perguntas
FIT- Metrocamp 2016 3
Apresentação
● Desenvolvimento de Software no Centro de
Engenharia e Ciências Computacionais
Unicamp
● Software com foco em HPC
● Resolver problemas que exigem alto poder
computacional
FIT- Metrocamp 2016 4
Apresentação...
FIT- Metrocamp 2016 5
Apresentação...
Cluster Composition with Xeon Processor
1 Head node with 40 cores Intel Xeon E5-2660 v2 of 2.20GHz, 128G memory.
1 Login node with 40 cores HT Intel Xeon E5-2660 v2 of 2.20GHz, 128G memory and
1 Nvidia Quadro 4000 card.
32 Graphic nodes with 40 cores HT Intel Xeon E5-2670 v2 of 2.50GHz, 64G memory
and 2 Nvidia Tesla K20M card.
1 UV20 node with 64 cores HT Intel Xeon E5-4650L of 2.60GHz, 1TB memory and 1
Intel Xeon-Phi card with 57 cores.
1 Storage node with 32 cores HT Intel Xeon E5-2660 of 2.20GHz, 128G memory and
56 disks of 4TB in RAID6 array.
Interconnection with Gigabit Ethernet switch and Infiniband 40 Gb/sec (4X QDR)
switch
The cluster is connected to two UPSs in parallel to 20kV and IQ of the diesel
generator.
Total Cluster Memory - 3,3 TB
Theoretical Performance Total Cluster - 96 Tflops
FIT- Metrocamp 2016 6
Introdução
● Processadores eram Seriais (até ± 2006)
● A cada nova geração Aumentava a sua
frequência (+ transistors, litografia menor)
● Algumas novas tecnologias foram sendo
adicionadas (Ex. Cache – SSE – AVX – VT
– TM)
FIT- Metrocamp 2016 7
Introdução Evolução CPU
FIT- Metrocamp 2016 8
Introdução
Lei de Moore
O número de transistores dos
chips teria um aumento de
100%, pelo mesmo custo, a
cada período de 18 meses
FIT- Metrocamp 2016 9
Introdução
Memory Wall
O aumento da lacuna entre a velocidade da CPU e Memória
ILP Wall
O aumento da dificuldade em encontrar paralelismo suficiente em um único fluxo
de instrução para manter alta performance em um processador com um só núcleo
The power wall
Ao aumentar a frequencia do processador temos um aumento do consumo de
energia tornando inviável com os sistemas de resfriamento mais baratos.
FIT- Metrocamp 2016 10
Introdução
Solução
● Diminuir a frequência
● Multicore
FIT- Metrocamp 2016 11
Motivação
● Aumento do número de cores disponíveis
● Novas tecnologias para aumentar o
desempenho dos códigos
● Surgimento de GPUs e Coprocesadores
● Qualquer smartphone produzido hoje tem
no mínimo 2 cores
FIT- Metrocamp 2016 12
OpenMP
● API para programação Multi-core
● Utiliza Memória Compartilhada
● Multiplas Plataformas
● Suporta C / C++ e Fortran
FIT- Metrocamp 2016 13
OpenMP – Conceitos básicos
● Core
● Thread
● Condições de Corridas
● Speedup
● Eficiência
FIT- Metrocamp 2016 14
OpenMP – Conceitos básicos
Fork - Join
Master Thread 1
2
4
threads
região paralela
threads
região paralela
3
1
2
3
FIT- Metrocamp 2016 15
OpenMP
Hello Word!
#include <stdio.h>
int main () {
printf("Hello World!");
return 0;
}
Serial
FIT- Metrocamp 2016 16
OpenMP
Hello Word!
#include <stdio.h>
int main () {
printf("Hello World!");
return 0;
}
Serial
Paralelo
#include <omp.h>
#include <stdio.h>
int main () {
#pragma omp parallel
{
printf("Hello World!");
}
return 0;
}
FIT- Metrocamp 2016 17
OpenMP
SAXPY z = Ax + y
#include <stdio.h>
#define N 1000000
#define A 10
int main () {
int i, z[N], x[N], y[N];
for(i = 0; i < N; i++){
z[i] = A * x[i] + y[i];
}
return 0;
}
Serial
FIT- Metrocamp 2016 18
OpenMP
SAXPY z = Ax + y
#include <stdio.h>
#define N 1000000
#define A 10
int main () {
int i, z[N], x[N], y[N];
for(i = 0; i < N; i++){
z[i] = A * x[i] + y[i];
}
return 0;
}
Serial
#pragma omp parallel for
for(i = 0; i < N; i++){
z[i] = A * x[i] + y[i];
}
Paralelo
FIT- Metrocamp 2016 19
OpenMP
Pool de Threads
int main () {
for(i = 0; i < N; i++){
z[i] = A * x[i] + y[i];
}
for(i = 0; i < N; i++){
z[i] = A * x[i] / y[i];
}
return 0;
}
Serial
FIT- Metrocamp 2016 20
OpenMP
Pool de Threads
int main () {
for(i = 0; i < N; i++){
z[i] = A * x[i] + y[i];
}
for(i = 0; i < N; i++){
z[i] = A * x[i] / y[i];
}
return 0;
}
Serial
#pragma omp parallel
{
#pragma omp for
for(i = 0; i < N; i++){
z[i] = A * x[i] + y[i];
}
#pragma omp for
for(i = 0; i < N; i++){
z[i] = A * x[i] / y[i];
}
}
Paralelo
FIT- Metrocamp 2016 21
OpenMP
Scheduling
● A cargas de trabalho nem sempre são do mesmo tamanho
● Veremos 3 maneiras de dividir a carga de trabalho
✔ Static
✔ Dynamic
✔ Guided
FIT- Metrocamp 2016 22
OpenMP
Scheduling - Static
Divide o loop em pedaços de tamanhos iguais ou quanto possivel no caso do numero de
iterações não serem divisíveis pelo número de threads multiplicados pelo tamanho do
pedaço.
#pragma omp parallel for schedule(static)
for(i = 0; i < N; i++){
z[i] = A * x[i] + y[i];
}
T0 T1 T2 T3
T0 T1 T2 T3 T0 T1 T2 T3 T0 T1 T2 T3
static,1
static,3
FIT- Metrocamp 2016 23
OpenMP
Scheduling - Dynamic
Usa a fila de trabalho interna para dar o tamanho do pedaço do bloco das iterações de
cada thread. Quando uma thread termina, ele pega o próximo bloco de iterações do loop
do topo da fila.
#pragma omp parallel for schedule(dynamic)
for(i = 0; i < N; i++){
z[i] = A * x[i] + y[i];
}
T0 T1T2 T3 T0T1T2 T3 T0T1 T2 T3
dynamic,3
FIT- Metrocamp 2016 24
OpenMP
Scheduling - Guided
Similar ao dynamic scheduling, porém o tamanho começa em um tamanho maior e vai
diminuindo para lidar com o desbalanceamento entre as iterações.
#pragma omp parallel for schedule(guided)
for(i = 0; i < N; i++){
z[i] = A * x[i] + y[i];
}
T0 T1T2 T3 T0T1T2 T3 T0T1 T2 T3
guided,3
FIT- Metrocamp 2016 25
OpenMP
Reduction
A redução consiste em realizar uma operação em todos os elementos de um vetor.
#pragma omp parallel for reduction(+:sum)
for(i = 0; i < N; i++){
sum += A * x[i] + y[i];
}
5 4 36
11 7
18
+ + +
+
FIT- Metrocamp 2016 26
OpenMP
Private – Shared – Atomic
#pragma omp parallel for private(w)
for(i = 0; i < N; i++){
w = x[i] * y[i];
z[i] = A * x[i] + y[i];
}
Private
#pragma omp parallel for private(z)
for(i = 0; i < N; i++){
z[i] = A * x[i] + y[i];
#pragma omp atomic
sum++;
}
Atomic
#pragma omp parallel for shared(A)
for(i = 0; i < N; i++){
z = x[i] * y[i];
z[i] = A * x[i] + y[i];
}
Shared
FIT- Metrocamp 2016 27
OpenMP
Critical Session – Master - Single
#pragma omp parallel
{
#pragma omp critical{
sum(a,b);
}
}
Critical
Single
Master
#pragma omp parallel
{
#pragma omp master{
sum(a,b);
}
}
#pragma omp parallel
{
#pragma omp single{
sum(a,b);
}
}
FIT- Metrocamp 2016 28
Profile
Não advinhe, meça!
FIT- Metrocamp 2016 29
Profile
Existem ferramentas que auxiliam a identificar trechos em potencial,
afim de aumentar o desempenho
✔ Gprof
✔ Valgrind
✔ Intel Vtune
FIT- Metrocamp 2016 30
Profile
Gprof
FIT- Metrocamp 2016 31
Profile
Valgrind
FIT- Metrocamp 2016 32
Profile
Intel Vtune
FIT- Metrocamp 2016 33
Profile
Intel Vtune
FIT- Metrocamp 2016 34
CUDA
Compute Unified Device Architecture
● Desenvolvido pela Nvidia – 2006
● Arquitetura
● Programação com CUDA
FIT- Metrocamp 2016 35
CPUs: Latency Oriented
Design
• Large caches
– Convert long latency
memory accesses to short
latency cache accesses
• Sophisticated control
– Branch prediction for
reduced branch latency
– Data forwarding for
reduced data latency
• Powerful ALU
– Reduced operation latency
© David Kirk/NVIDIA and Wen-mei W. Hwu, 2007-2012,
SSL 2014, ECE408/CS483, University of Illinois, Urbana-
Champaign
Cache
ALU
Control
ALU
ALU
ALU
DRAM
CPU
FIT- Metrocamp 2016 36
GPUs: Throughput Oriented
Design
• Small caches
– To boost memory throughput
• Simple control
– No branch prediction
– No data forwarding
• Energy efficient ALUs
– Many, long latency but heavily
pipelined for high throughput
• Require massive number of
threads to tolerate latencies
© David Kirk/NVIDIA and Wen-mei W. Hwu, 2007-2012,
SSL 2014, ECE408/CS483, University of Illinois, Urbana-
Champaign
DRAM
GPU
FIT- Metrocamp 2016 37
The Era of Fixed-Function
Graphics Pipelines
3D Graphics Rendering Pipeline
FIT- Metrocamp 2016 38
Programmable OpenGL pipeline with the
vertex and fragment processors
FIT- Metrocamp 2016 39
G80 Architecture
FIT- Metrocamp 2016 40
Pascal Architecture
FIT- Metrocamp 2016 41
Programação com CUDA
PCIe Bus
Host Device
FIT- Metrocamp 2016 42
Programação com CUDA
void saxpy(int n, float a, float *x, float *y, float *z)
{
for(int i = 0; i < n; i++){
z[i] = a * x[i] + y[i];
}
Serial
SAXPY z = Ax + y
FIT- Metrocamp 2016 43
Programação com CUDA
__global__ void saxpy(int n, float a, float *x, float *y, float *z)
{
tid = threadIdx.x + blockDim.x * blockIdx.x ;
if (tid < n) {
z[tid] = a * x[tid] + y[tid];
}
}
CUDA
SAXPY z = Ax + y
FIT- Metrocamp 2016 44
Programação com CUDA
CUDA – Chamada do Host
SAXPY z = Ax + y
//Configuração do Bloco e da Grid
dim3 dimBlock(256,1,1);
dim3 dimGrid(ceil(n/256.0),1,1);
int *h_a, *h_b, *h_c;
int *d_a, *d_b, *d_c;
unsigned int n, size;
n = 1000000;
//Alocando as variveis no host
h_a = (int*)malloc(n * sizeof(int));
h_b = (int*)malloc(n * sizeof(int));
h_c = (int*)malloc(n * sizeof(int));
//Alocando as variaveis no device
size = n * sizeof(int);
cudaMalloc((void**)&d_a,size);
cudaMalloc((void**)&d_b,size);
cudaMalloc((void**)&d_c,size);
//Gerar os valores para os vetores a e b
//Copiar os dados do Host para o Device
cudaMemcpy(d_a,h_a,size,cudaMemcpyHostToDevice);
cudaMemcpy(d_b,h_b,size,cudaMemcpyHostToDevice);
vecAddKernel<<<ceil(n/256.0),256>>>(d_a,d_b,d_c,n);
//Copiar o resultado do Device para o Host
cudaMemcpy(h_c,d_c,size,cudaMemcpyDeviceToHost);
//Liberar Memória do Host
free(h_a); free(h_b); free(h_c);
//Liberar Memória do Device
cudaFree(d_a); cudaFree(d_b); cudaFree(d_c);
FIT- Metrocamp 2016 45
Programação com CUDA
Threads - Blocks - Grids
© David Kirk/NVIDIA and Wen-mei W. Hwu, 2007-2011, SSL
2014, ECE408/CS483, University of Illinois, Urbana-Champaign
• Each thread uses indices to
decide what data to work on
– blockIdx: 1D, 2D, or 3D
– threadIdx: 1D, 2D, or 3D
• Simplifies memory
addressing when processing
multidimensional data
– Image processing
FIT- Metrocamp 2016 46
Programação com CUDA
Um CUDA Kernel em um Grid que possui um conjunto de threads
__global__ void saxpy(int n, float a, float *x, float *y, float *z)
{
tid = threadIdx.x + blockDim.x * blockIdx.x ;
if (tid < n) {
z[tid] = a * x[tid] + y[tid];
}
}
...0 1 2 3 254 255
FIT- Metrocamp 2016 47
Programação com CUDA
Thread Blocks
...0 1 2 3 254 255
__global__ void saxpy(int n, float a, float *x, float *y, float *z)
{
tid = threadIdx.x + blockDim.x * blockIdx.x ;
if (tid < n) {
z[tid] = a * x[tid] + y[tid];
}
}
Thread Block 0
...0 1 2 3 254 255
__global__ void saxpy(int n, float a, float *x, float *y, float *z)
{
tid = threadIdx.x + blockDim.x * blockIdx.x ;
if (tid < n) {
z[tid] = a * x[tid] + y[tid];
}
}
Thread Block N - 1...
FIT- Metrocamp 2016 48
Programação com CUDA
GPU Memory
Grid
Constant
Memory
Texture
Memory
Global
Memory
Block (0, 0)
Shared Memory
Local
Memory
Thread (0, 0)
Registers
Local
Memory
Thread (1, 0)
Registers
Block (1, 0)
Shared Memory
Local
Memory
Thread (0, 0)
Registers
Local
Memory
Thread (1, 0)
Registers
● __global__
● __shared__
● __constant__
FIT- Metrocamp 2016 49
Programação com CUDA
Compilando
C source code with CUDA extensions
NVCC Compiler
Host C Compiler/
Linker
Host Code Device Code (PTX)
Device Just-in-Time
Compiler
Heterogeneous Computing Platform withHeterogeneous Computing Platform with
CPUs, GPUsCPUs, GPUs
FIT- Metrocamp 2016 50
Perguntas

Fit Metrocamp 2016

  • 1.
    Paralelização com OpenMP -CUDA FIT - Metrocamp 2016
  • 2.
    FIT- Metrocamp 20162 Agenda ● Apresentação ● Introdução ● Motivação ● OpenMP ● CUDA ● Otimização ● Perguntas
  • 3.
    FIT- Metrocamp 20163 Apresentação ● Desenvolvimento de Software no Centro de Engenharia e Ciências Computacionais Unicamp ● Software com foco em HPC ● Resolver problemas que exigem alto poder computacional
  • 4.
    FIT- Metrocamp 20164 Apresentação...
  • 5.
    FIT- Metrocamp 20165 Apresentação... Cluster Composition with Xeon Processor 1 Head node with 40 cores Intel Xeon E5-2660 v2 of 2.20GHz, 128G memory. 1 Login node with 40 cores HT Intel Xeon E5-2660 v2 of 2.20GHz, 128G memory and 1 Nvidia Quadro 4000 card. 32 Graphic nodes with 40 cores HT Intel Xeon E5-2670 v2 of 2.50GHz, 64G memory and 2 Nvidia Tesla K20M card. 1 UV20 node with 64 cores HT Intel Xeon E5-4650L of 2.60GHz, 1TB memory and 1 Intel Xeon-Phi card with 57 cores. 1 Storage node with 32 cores HT Intel Xeon E5-2660 of 2.20GHz, 128G memory and 56 disks of 4TB in RAID6 array. Interconnection with Gigabit Ethernet switch and Infiniband 40 Gb/sec (4X QDR) switch The cluster is connected to two UPSs in parallel to 20kV and IQ of the diesel generator. Total Cluster Memory - 3,3 TB Theoretical Performance Total Cluster - 96 Tflops
  • 6.
    FIT- Metrocamp 20166 Introdução ● Processadores eram Seriais (até ± 2006) ● A cada nova geração Aumentava a sua frequência (+ transistors, litografia menor) ● Algumas novas tecnologias foram sendo adicionadas (Ex. Cache – SSE – AVX – VT – TM)
  • 7.
    FIT- Metrocamp 20167 Introdução Evolução CPU
  • 8.
    FIT- Metrocamp 20168 Introdução Lei de Moore O número de transistores dos chips teria um aumento de 100%, pelo mesmo custo, a cada período de 18 meses
  • 9.
    FIT- Metrocamp 20169 Introdução Memory Wall O aumento da lacuna entre a velocidade da CPU e Memória ILP Wall O aumento da dificuldade em encontrar paralelismo suficiente em um único fluxo de instrução para manter alta performance em um processador com um só núcleo The power wall Ao aumentar a frequencia do processador temos um aumento do consumo de energia tornando inviável com os sistemas de resfriamento mais baratos.
  • 10.
    FIT- Metrocamp 201610 Introdução Solução ● Diminuir a frequência ● Multicore
  • 11.
    FIT- Metrocamp 201611 Motivação ● Aumento do número de cores disponíveis ● Novas tecnologias para aumentar o desempenho dos códigos ● Surgimento de GPUs e Coprocesadores ● Qualquer smartphone produzido hoje tem no mínimo 2 cores
  • 12.
    FIT- Metrocamp 201612 OpenMP ● API para programação Multi-core ● Utiliza Memória Compartilhada ● Multiplas Plataformas ● Suporta C / C++ e Fortran
  • 13.
    FIT- Metrocamp 201613 OpenMP – Conceitos básicos ● Core ● Thread ● Condições de Corridas ● Speedup ● Eficiência
  • 14.
    FIT- Metrocamp 201614 OpenMP – Conceitos básicos Fork - Join Master Thread 1 2 4 threads região paralela threads região paralela 3 1 2 3
  • 15.
    FIT- Metrocamp 201615 OpenMP Hello Word! #include <stdio.h> int main () { printf("Hello World!"); return 0; } Serial
  • 16.
    FIT- Metrocamp 201616 OpenMP Hello Word! #include <stdio.h> int main () { printf("Hello World!"); return 0; } Serial Paralelo #include <omp.h> #include <stdio.h> int main () { #pragma omp parallel { printf("Hello World!"); } return 0; }
  • 17.
    FIT- Metrocamp 201617 OpenMP SAXPY z = Ax + y #include <stdio.h> #define N 1000000 #define A 10 int main () { int i, z[N], x[N], y[N]; for(i = 0; i < N; i++){ z[i] = A * x[i] + y[i]; } return 0; } Serial
  • 18.
    FIT- Metrocamp 201618 OpenMP SAXPY z = Ax + y #include <stdio.h> #define N 1000000 #define A 10 int main () { int i, z[N], x[N], y[N]; for(i = 0; i < N; i++){ z[i] = A * x[i] + y[i]; } return 0; } Serial #pragma omp parallel for for(i = 0; i < N; i++){ z[i] = A * x[i] + y[i]; } Paralelo
  • 19.
    FIT- Metrocamp 201619 OpenMP Pool de Threads int main () { for(i = 0; i < N; i++){ z[i] = A * x[i] + y[i]; } for(i = 0; i < N; i++){ z[i] = A * x[i] / y[i]; } return 0; } Serial
  • 20.
    FIT- Metrocamp 201620 OpenMP Pool de Threads int main () { for(i = 0; i < N; i++){ z[i] = A * x[i] + y[i]; } for(i = 0; i < N; i++){ z[i] = A * x[i] / y[i]; } return 0; } Serial #pragma omp parallel { #pragma omp for for(i = 0; i < N; i++){ z[i] = A * x[i] + y[i]; } #pragma omp for for(i = 0; i < N; i++){ z[i] = A * x[i] / y[i]; } } Paralelo
  • 21.
    FIT- Metrocamp 201621 OpenMP Scheduling ● A cargas de trabalho nem sempre são do mesmo tamanho ● Veremos 3 maneiras de dividir a carga de trabalho ✔ Static ✔ Dynamic ✔ Guided
  • 22.
    FIT- Metrocamp 201622 OpenMP Scheduling - Static Divide o loop em pedaços de tamanhos iguais ou quanto possivel no caso do numero de iterações não serem divisíveis pelo número de threads multiplicados pelo tamanho do pedaço. #pragma omp parallel for schedule(static) for(i = 0; i < N; i++){ z[i] = A * x[i] + y[i]; } T0 T1 T2 T3 T0 T1 T2 T3 T0 T1 T2 T3 T0 T1 T2 T3 static,1 static,3
  • 23.
    FIT- Metrocamp 201623 OpenMP Scheduling - Dynamic Usa a fila de trabalho interna para dar o tamanho do pedaço do bloco das iterações de cada thread. Quando uma thread termina, ele pega o próximo bloco de iterações do loop do topo da fila. #pragma omp parallel for schedule(dynamic) for(i = 0; i < N; i++){ z[i] = A * x[i] + y[i]; } T0 T1T2 T3 T0T1T2 T3 T0T1 T2 T3 dynamic,3
  • 24.
    FIT- Metrocamp 201624 OpenMP Scheduling - Guided Similar ao dynamic scheduling, porém o tamanho começa em um tamanho maior e vai diminuindo para lidar com o desbalanceamento entre as iterações. #pragma omp parallel for schedule(guided) for(i = 0; i < N; i++){ z[i] = A * x[i] + y[i]; } T0 T1T2 T3 T0T1T2 T3 T0T1 T2 T3 guided,3
  • 25.
    FIT- Metrocamp 201625 OpenMP Reduction A redução consiste em realizar uma operação em todos os elementos de um vetor. #pragma omp parallel for reduction(+:sum) for(i = 0; i < N; i++){ sum += A * x[i] + y[i]; } 5 4 36 11 7 18 + + + +
  • 26.
    FIT- Metrocamp 201626 OpenMP Private – Shared – Atomic #pragma omp parallel for private(w) for(i = 0; i < N; i++){ w = x[i] * y[i]; z[i] = A * x[i] + y[i]; } Private #pragma omp parallel for private(z) for(i = 0; i < N; i++){ z[i] = A * x[i] + y[i]; #pragma omp atomic sum++; } Atomic #pragma omp parallel for shared(A) for(i = 0; i < N; i++){ z = x[i] * y[i]; z[i] = A * x[i] + y[i]; } Shared
  • 27.
    FIT- Metrocamp 201627 OpenMP Critical Session – Master - Single #pragma omp parallel { #pragma omp critical{ sum(a,b); } } Critical Single Master #pragma omp parallel { #pragma omp master{ sum(a,b); } } #pragma omp parallel { #pragma omp single{ sum(a,b); } }
  • 28.
    FIT- Metrocamp 201628 Profile Não advinhe, meça!
  • 29.
    FIT- Metrocamp 201629 Profile Existem ferramentas que auxiliam a identificar trechos em potencial, afim de aumentar o desempenho ✔ Gprof ✔ Valgrind ✔ Intel Vtune
  • 30.
    FIT- Metrocamp 201630 Profile Gprof
  • 31.
    FIT- Metrocamp 201631 Profile Valgrind
  • 32.
    FIT- Metrocamp 201632 Profile Intel Vtune
  • 33.
    FIT- Metrocamp 201633 Profile Intel Vtune
  • 34.
    FIT- Metrocamp 201634 CUDA Compute Unified Device Architecture ● Desenvolvido pela Nvidia – 2006 ● Arquitetura ● Programação com CUDA
  • 35.
    FIT- Metrocamp 201635 CPUs: Latency Oriented Design • Large caches – Convert long latency memory accesses to short latency cache accesses • Sophisticated control – Branch prediction for reduced branch latency – Data forwarding for reduced data latency • Powerful ALU – Reduced operation latency © David Kirk/NVIDIA and Wen-mei W. Hwu, 2007-2012, SSL 2014, ECE408/CS483, University of Illinois, Urbana- Champaign Cache ALU Control ALU ALU ALU DRAM CPU
  • 36.
    FIT- Metrocamp 201636 GPUs: Throughput Oriented Design • Small caches – To boost memory throughput • Simple control – No branch prediction – No data forwarding • Energy efficient ALUs – Many, long latency but heavily pipelined for high throughput • Require massive number of threads to tolerate latencies © David Kirk/NVIDIA and Wen-mei W. Hwu, 2007-2012, SSL 2014, ECE408/CS483, University of Illinois, Urbana- Champaign DRAM GPU
  • 37.
    FIT- Metrocamp 201637 The Era of Fixed-Function Graphics Pipelines 3D Graphics Rendering Pipeline
  • 38.
    FIT- Metrocamp 201638 Programmable OpenGL pipeline with the vertex and fragment processors
  • 39.
    FIT- Metrocamp 201639 G80 Architecture
  • 40.
    FIT- Metrocamp 201640 Pascal Architecture
  • 41.
    FIT- Metrocamp 201641 Programação com CUDA PCIe Bus Host Device
  • 42.
    FIT- Metrocamp 201642 Programação com CUDA void saxpy(int n, float a, float *x, float *y, float *z) { for(int i = 0; i < n; i++){ z[i] = a * x[i] + y[i]; } Serial SAXPY z = Ax + y
  • 43.
    FIT- Metrocamp 201643 Programação com CUDA __global__ void saxpy(int n, float a, float *x, float *y, float *z) { tid = threadIdx.x + blockDim.x * blockIdx.x ; if (tid < n) { z[tid] = a * x[tid] + y[tid]; } } CUDA SAXPY z = Ax + y
  • 44.
    FIT- Metrocamp 201644 Programação com CUDA CUDA – Chamada do Host SAXPY z = Ax + y //Configuração do Bloco e da Grid dim3 dimBlock(256,1,1); dim3 dimGrid(ceil(n/256.0),1,1); int *h_a, *h_b, *h_c; int *d_a, *d_b, *d_c; unsigned int n, size; n = 1000000; //Alocando as variveis no host h_a = (int*)malloc(n * sizeof(int)); h_b = (int*)malloc(n * sizeof(int)); h_c = (int*)malloc(n * sizeof(int)); //Alocando as variaveis no device size = n * sizeof(int); cudaMalloc((void**)&d_a,size); cudaMalloc((void**)&d_b,size); cudaMalloc((void**)&d_c,size); //Gerar os valores para os vetores a e b //Copiar os dados do Host para o Device cudaMemcpy(d_a,h_a,size,cudaMemcpyHostToDevice); cudaMemcpy(d_b,h_b,size,cudaMemcpyHostToDevice); vecAddKernel<<<ceil(n/256.0),256>>>(d_a,d_b,d_c,n); //Copiar o resultado do Device para o Host cudaMemcpy(h_c,d_c,size,cudaMemcpyDeviceToHost); //Liberar Memória do Host free(h_a); free(h_b); free(h_c); //Liberar Memória do Device cudaFree(d_a); cudaFree(d_b); cudaFree(d_c);
  • 45.
    FIT- Metrocamp 201645 Programação com CUDA Threads - Blocks - Grids © David Kirk/NVIDIA and Wen-mei W. Hwu, 2007-2011, SSL 2014, ECE408/CS483, University of Illinois, Urbana-Champaign • Each thread uses indices to decide what data to work on – blockIdx: 1D, 2D, or 3D – threadIdx: 1D, 2D, or 3D • Simplifies memory addressing when processing multidimensional data – Image processing
  • 46.
    FIT- Metrocamp 201646 Programação com CUDA Um CUDA Kernel em um Grid que possui um conjunto de threads __global__ void saxpy(int n, float a, float *x, float *y, float *z) { tid = threadIdx.x + blockDim.x * blockIdx.x ; if (tid < n) { z[tid] = a * x[tid] + y[tid]; } } ...0 1 2 3 254 255
  • 47.
    FIT- Metrocamp 201647 Programação com CUDA Thread Blocks ...0 1 2 3 254 255 __global__ void saxpy(int n, float a, float *x, float *y, float *z) { tid = threadIdx.x + blockDim.x * blockIdx.x ; if (tid < n) { z[tid] = a * x[tid] + y[tid]; } } Thread Block 0 ...0 1 2 3 254 255 __global__ void saxpy(int n, float a, float *x, float *y, float *z) { tid = threadIdx.x + blockDim.x * blockIdx.x ; if (tid < n) { z[tid] = a * x[tid] + y[tid]; } } Thread Block N - 1...
  • 48.
    FIT- Metrocamp 201648 Programação com CUDA GPU Memory Grid Constant Memory Texture Memory Global Memory Block (0, 0) Shared Memory Local Memory Thread (0, 0) Registers Local Memory Thread (1, 0) Registers Block (1, 0) Shared Memory Local Memory Thread (0, 0) Registers Local Memory Thread (1, 0) Registers ● __global__ ● __shared__ ● __constant__
  • 49.
    FIT- Metrocamp 201649 Programação com CUDA Compilando C source code with CUDA extensions NVCC Compiler Host C Compiler/ Linker Host Code Device Code (PTX) Device Just-in-Time Compiler Heterogeneous Computing Platform withHeterogeneous Computing Platform with CPUs, GPUsCPUs, GPUs
  • 50.
    FIT- Metrocamp 201650 Perguntas