GPU ¡PROGRAMMING ¡
GPU ¡Programming ¡
1 ¡
GPU PROGRAMMING 2 GPU Programming Assignment 4 Consists - - PowerPoint PPT Presentation
1 GPU Programming GPU PROGRAMMING 2 GPU Programming Assignment 4 Consists of two programming assignments Concurrency GPU programming Requires a
GPU ¡Programming ¡
1 ¡
GPU ¡
GPU ¡Programming ¡
2 ¡
GPU ¡Programming ¡
3 ¡
GPU ¡Programming ¡
4 ¡
GPU ¡Programming ¡
5 ¡
CPU 0 CPU 1 CPU 2 CPU 3 L2 Cache
SIMD SIMD SIMD SIMD SIMD SIMD SIMD SIMD SIMD SIMD SIMD SIMD SIMD SIMD SIMD SIMD SIMD SIMD L2 Cache SIMD SIMD SIMD SIMD SIMD SIMD SIMD SIMD SIMD SIMD SIMD SIMD SIMD SIMD SIMD SIMD SIMD SIMD SIMD SIMD SIMD SIMD
8 ¡
CPU 50GFlops GPU 1TFlop CPU RAM 4-6 GB GPU RAM 1 GB 10GB/s ¡ 100GB/s ¡ 1GB/s ¡ All ¡values ¡are ¡approximate ¡
GPU ¡Programming ¡
GPU ¡Programming ¡ 9 ¡
confusing) ¡names ¡
GPU ¡Programming ¡
10 ¡
GPU Programming 11 ¡
GPU ¡Programming ¡
12 ¡
addresses ¡
GPU ¡Programming ¡
13 ¡
Kernel: … i = input[tid];
…
addresses ¡
control ¡flow ¡
GPU ¡Programming ¡
14 ¡
Kernel: … i = input[tid]; if(i%2 == 0)
else
…
GPU ¡Programming ¡
15 ¡
Host Kernel 1 Kernel 2 Device Grid 1 Block (0, 0) Block (1, 0) Block (0, 1) Block (1, 1) Grid 2
GPU ¡Programming ¡
16 ¡
Host Kernel 1 Kernel 2 Device Grid 1 Block (0, 0) Block (1, 0) Block (0, 1) Block (1, 1) Grid 2 Thread ¡ (0,0) ¡ Thread ¡ (1,0) ¡ Thread ¡ (0,1) ¡ Thread ¡ (1,1) ¡
GPU ¡Programming ¡
17 ¡
CUDA Thread Block
Thread Id #: 0 1 2 3 … m Thread program
Courtesy: ¡John ¡Nickolls, ¡NVIDIA ¡
GPU ¡Programming ¡
18 ¡
host host __host__ float HostFunc() host device __global__ void KernelFunc() device device __device__ float DeviceFunc() Only callable from the: Executed
GPU ¡Programming ¡ 19 ¡
GPU ¡Programming ¡
20 ¡
__global__ void KernelFunc(…) dim3 DimGrid(100, 50); dim3 DimBlock(4, 8, 8); KernelFunc<<< DimGrid, DimBlock >>>(...);
GPU ¡Programming ¡
21 ¡
Grid Global Memory Block (0, 0)
Shared Memory Thread (0, 0) Registers Thread (1, 0) Registers
Block (1, 0)
Shared Memory Thread (0, 0) Registers Thread (1, 0) Registers
Host Constant Memory Texture Memory
GPU ¡Programming ¡
22 ¡
Grid Global Memory Block (0, 0)
Shared Memory Thread (0, 0) Registers Thread (1, 0) Registers
Block (1, 0)
Shared Memory Thread (0, 0) Registers Thread (1, 0) Registers
Host Constant Memory Texture Memory
GPU ¡Programming ¡ 23 ¡
Variable declaration Memory Scope Lifetime
__device__ __local__ int LocalVar;
local thread thread
__device__ __shared__ int SharedVar;
shared block block
__device__ int GlobalVar;
global grid application
__device__ __constant__ int ConstantVar;
constant grid application
GPU ¡Programming ¡ 24 ¡
__global__ void KernelFunc(float* ptr)
float* ptr = &GlobalVar;
GPU ¡Programming ¡
25 ¡
GPU ¡Programming ¡ 26 ¡
global ¡memory ¡ M N P
WIDTH WIDTH WIDTH WIDTH
GPU ¡Programming ¡
27 ¡
float *M, *N, *P; int width; int size = width * width * sizeof(float);
cudaMalloc(&Md, size); cudaMemcpy(Md, M, size, cudaMemcpyHostToDevice);
GPU ¡Programming ¡
28 ¡
float *M, *N, *P; int width; int size = width * width * sizeof(float);
cudaMalloc(&Md, size); cudaMemcpy(Md, M, size, cudaMemcpyHostToDevice); cudaMalloc(&Nd, size); cudaMemcpy(Nd, N, size, cudaMemcpyHostToDevice); cudaMalloc(&Pd, size);
GPU ¡Programming ¡
29 ¡
float *M, *N, *P; int width; int size = width * width * sizeof(float);
cudaMalloc(&Md, size); cudaMemcpy(Md, M, size, cudaMemcpyHostToDevice); cudaMalloc(&Nd, size); cudaMemcpy(Nd, N, size, cudaMemcpyHostToDevice); cudaMalloc(&Pd, size); // call kernel cudaMemcpy(P, Pd, size, cudaMemcpyDeviceToHost);
GPU ¡Programming ¡
30 ¡
float *M, *N, *P; int width; int size = width * width * sizeof(float);
cudaMalloc(&Md, size); cudaMemcpy(Md, M, size, cudaMemcpyHostToDevice); cudaMalloc(&Nd, size); cudaMemcpy(Nd, N, size, cudaMemcpyHostToDevice); cudaMalloc(&Pd, size); // call kernel cudaMemcpy(P, Pd, size, cudaMemcpyDeviceToHost); cudaFree(Md); cudaFree(Nd); cudaFree(Pd);
GPU ¡Programming ¡
31 ¡
M N P
WIDTH WIDTH WIDTH WIDTH
GPU ¡Programming ¡
32 ¡
M N P
WIDTH WIDTH WIDTH WIDTH
dim3 dimGrid(1,1); dim3 dimBlock(width, width); MatrixMul<<<dimGrid, dimBlock>>> (Md, Nd, Pd, width);
GPU ¡Programming ¡
33 ¡
__global__ void MatrixMul( float* Md, float* Nd, float* Pd, int width) { Pd[ty*width + tx] = … }
Md Nd Pd
WIDTH WIDTH WIDTH WIDTH
tx ty
short forms: tx = threadIdx.x; ty = threadIdx.y;
GPU ¡Programming ¡
34 ¡
__global__ void MatrixMul(…){ for(k=0; k<width; k++){ r = Md[ty*width+k] + Nd[k*width+tx]; Pd[ty*width + tx] = r; }}
Md Nd Pd
WIDTH WIDTH WIDTH WIDTH
tx ty
GPU ¡Programming ¡
35 ¡
matrix ¡Pd ¡
element ¡of ¡Pd ¡
addiBon ¡for ¡each ¡pair ¡of ¡Md ¡and ¡ Nd ¡elements ¡
access ¡raBo ¡close ¡to ¡1:1 ¡(not ¡very ¡ high) ¡
number ¡of ¡threads ¡allowed ¡in ¡a ¡ thread ¡block ¡
Grid 1 Block 1
48
Thread )2 ,2(
WIDTH
Md Pd Nd
GPU ¡Programming ¡ 36 ¡ Grid Global Memory Block (0, 0)
Shared Memory Thread (0, 0) Registers Thread (1, 0) Registers
Block (1, 0)
Shared Memory Thread (0, 0) Registers Thread (1, 0) Registers
Host Constant Memory
their ¡input ¡matrix ¡elements ¡
GPU ¡Programming ¡ 37 ¡ Grid Global Memory Block (0, 0)
Shared Memory Thread (0, 0) Registers Thread (1, 0) Registers
Block (1, 0)
Shared Memory Thread (0, 0) Registers Thread (1, 0) Registers
Host Constant Memory
input ¡matrix ¡elements ¡
floaBng ¡point ¡mulBply-‑add ¡
achieve ¡peak ¡FLOP ¡raBng ¡
GFLOPS ¡
accesses ¡to ¡get ¡closer ¡to ¡the ¡peak ¡346.5 ¡ GFLOPS ¡
GPU ¡Programming ¡
38 ¡
MulBprocessors ¡in ¡block ¡granularity ¡
allows ¡
t0 t1 t2 … tm
Blocks
SP
Shared Memory
MT IU SP
Shared Memory
MT IU
t0 t1 t2 … tm
Blocks
SM 1 SM 0
GPU ¡Programming ¡ 39 ¡
thread Warps
– Warps are scheduling units in SM
SM and each block has 256 threads, how many Warps are there in an SM?
… ¡
t0 t1 t2 … t31
… ¡ … ¡
t0 t1 t2 … t31
… ¡
Block 1 Warps Block 2 Warps
SP SP SP SP SFU SP SP SP SP SFU Instruction Fetch/Dispatch Instruction L1
Streaming Multiprocessor
Shared Memory
… ¡
t0 t1 t2 … t31
… ¡
Block 1 Warps
GPU ¡Programming ¡ 40 ¡
thread Warps
– Warps are scheduling units in SM
SM and each block has 256 threads, how many Warps are there in an SM?
– Each Block is divided into 256/32 = 8 Warps – There are 8 * 3 = 24 Warps … ¡
t0 t1 t2 … t31
… ¡ … ¡
t0 t1 t2 … t31
… ¡
Block 1 Warps Block 2 Warps
SP SP SP SP SFU SP SP SP SP SFU Instruction Fetch/Dispatch Instruction L1
Streaming Multiprocessor
Shared Memory
… ¡
t0 t1 t2 … t31
… ¡
Block 1 Warps
GPU ¡Programming ¡
41 ¡
its ¡operands ¡ready ¡for ¡ consumpBon ¡are ¡eligible ¡for ¡ execuBon ¡
execuBon ¡on ¡a ¡prioriBzed ¡ scheduling ¡policy ¡
same ¡instrucBon ¡when ¡selected ¡
warp 8 instruction 11 SM multithreaded Warp scheduler warp 1 instruction 42 warp 3 instruction 95 warp 8 instruction 12 . . . time warp 3 instruction 96
GPU ¡Programming ¡ 42 ¡
8X8, ¡16X16 ¡or ¡32X32 ¡blocks? ¡
GPU ¡Programming ¡ 43 ¡
8X8, ¡16X16 ¡or ¡32X32 ¡blocks? ¡
threads, ¡there ¡are ¡12 ¡Blocks. ¡However, ¡each ¡SM ¡can ¡only ¡take ¡up ¡to ¡8 ¡ Blocks, ¡only ¡512 ¡threads ¡will ¡go ¡into ¡each ¡SM! ¡
768 ¡threads, ¡it ¡can ¡take ¡up ¡to ¡3 ¡Blocks ¡and ¡achieve ¡full ¡capacity ¡unless ¡
SM! ¡
GPU ¡Programming ¡ 44 ¡
mulBple ¡threads ¡to ¡exploit ¡memory-‑level ¡parallelism ¡
each ¡thread ¡can ¡efficiently ¡mulB-‑pass ¡over ¡any ¡data ¡element ¡
GPU ¡Programming ¡ 45 ¡
GPU ¡Programming ¡ 46 ¡
M N P
WIDTH WIDTH WIDTH WIDTH
ty ¡ tx ¡
GPU ¡Programming ¡ 47 ¡ Md Nd Pd Pdsub
TILE_WIDTH WIDTH WIDTH TILE_WIDTH TILE_WIDTH
bx tx
01 TILE_WIDTH-1 2 1 2
by ty
2 1 TILE_WIDTH-1 2 1
TILE_WIDTH TILE_WIDTH TILE_WIDTHE WIDTH WIDTH
GPU ¡Programming ¡ 48 ¡
Pd1,0 ¡
Md2,0 ¡ Md1,1 ¡ Md1,0 ¡ Md0,0 ¡ Md0,1 ¡ Md3,0 ¡ Md2,1 ¡ Pd0,0 ¡ Md3,1 ¡ Pd0,1 ¡ Pd2,0 ¡ Pd3,0 ¡ Nd0,3 ¡ Nd1,3 ¡ Nd1,2 ¡ Nd1,1 ¡ Nd1,0 ¡ Nd0,0 ¡ Nd0,1 ¡ Nd0,2 ¡ Pd1,1 ¡ Pd0,2 ¡ Pd2,2 ¡ Pd3,2 ¡ Pd1,2 ¡ Pd3,1 ¡ Pd2,1 ¡ Pd0,3 ¡ Pd2,3 ¡ Pd3,3 ¡ Pd1,3 ¡
GPU ¡Programming ¡
49 ¡
P0,0 thread0,0 P1,0 thread1,0 P0,1 thread0,1 P1,1 thread1,1 M0,0 * N0,0 M0,0 * N1,0 M0,1 * N0,0 M0,1 * N1,0 M1,0 * N0,1 M1,0 * N1,1 M1,1 * N0,1 M1,1 * N1,1 M2,0 * N0,2 M2,0 * N1,2 M2,1 * N0,2 M2,1 * N1,2 M3,0 * N0,3 M3,0 * N1,3 M3,1 * N0,3 M3,1 * N1,3 Access ¡
GPU ¡Programming ¡
50 ¡
P0,0 thread0,0 P1,0 thread1,0 P0,1 thread0,1 P1,1 thread1,1 M0,0 * N0,0 M0,0 * N1,0 M0,1 * N0,0 M0,1 * N1,0 M1,0 * N0,1 M1,0 * N1,1 M1,1 * N0,1 M1,1 * N1,1 M2,0 * N0,2 M2,0 * N1,2 M2,1 * N0,2 M2,1 * N1,2 M3,0 * N0,3 M3,0 * N1,3 M3,1 * N0,3 M3,1 * N1,3 Access ¡
GPU ¡Programming ¡
Pd1,0 ¡ Md2,0 ¡ Md1,1 ¡ Md1,0 ¡ Md0,0 ¡ Md0,1 ¡ Md3,0 ¡ Md2,1 ¡ Pd0,0 ¡ Md3,1 ¡ Pd0,1 ¡ Pd2,0 ¡Pd3,0 ¡ Nd0,3 ¡ Nd1,3 ¡ Nd1,2 ¡ Nd1,1 ¡ Nd1,0 ¡ Nd0,0 ¡ Nd0,1 ¡ Nd0,2 ¡ Pd1,1 ¡ Pd0,2 ¡ Pd2,2 ¡Pd3,2 ¡ Pd1,2 ¡ Pd3,1 ¡ Pd2,1 ¡ Pd0,3 ¡ Pd2,3 ¡Pd3,3 ¡ Pd1,3 ¡
loop ¡of ¡each ¡thread ¡into ¡ phases ¡
phase, ¡load ¡the ¡Md ¡and ¡Nd ¡ elements ¡that ¡everyone ¡ needs ¡during ¡the ¡phase ¡into ¡ shared ¡memory ¡
Nd ¡elements ¡from ¡the ¡ shared ¡memory ¡during ¡the ¡ phase ¡
GPU ¡Programming ¡
Pd1,0 ¡ Md2,0 ¡ Md1,1 ¡ Md1,0 ¡ Md0,0 ¡ Md0,1 ¡ Md3,0 ¡ Md2,1 ¡ Pd0,0 ¡ Md3,1 ¡ Pd0,1 ¡ Pd2,0 ¡Pd3,0 ¡ Nd0,3 ¡ Nd1,3 ¡ Nd1,2 ¡ Nd1,1 ¡ Nd1,0 ¡ Nd0,0 ¡ Nd0,1 ¡ Nd0,2 ¡ Pd1,1 ¡ Pd0,2 ¡ Pd2,2 ¡Pd3,2 ¡ Pd1,2 ¡ Pd3,1 ¡ Pd2,1 ¡ Pd0,3 ¡ Pd2,3 ¡Pd3,3 ¡ Pd1,3 ¡
loop ¡of ¡each ¡thread ¡into ¡ phases ¡
phase, ¡load ¡the ¡Md ¡and ¡Nd ¡ elements ¡that ¡everyone ¡ needs ¡during ¡the ¡phase ¡into ¡ shared ¡memory ¡
Nd ¡elements ¡from ¡the ¡ shared ¡memory ¡during ¡the ¡ phase ¡
GPU ¡Programming ¡
53 ¡
__global__ void Tiled(float* Md, float* Nd, float* Pd, int Width) { __shared __float Mds[TILE_WIDTH][TILE_WIDTH]; __shared __float Nds[TILE_WIDTH][TILE_WIDTH]; int bx = blockIdx.x; int by = blockIdx.y; int tx = threadIdx.x; int ty = threadIdx.y; // Identify the row and column of the Pd element to work on int Row = by * TILE_WIDTH + ty; int Col = bx * TILE_WIDTH + tx; float Pvalue = 0; // compute Pvalue Pd[Row*Width + Col] = Pvalue; }
GPU ¡Programming ¡
54 ¡
//… float Pvalue = 0; // Loop over the Md and Nd tiles required for (int m = 0; m < Width/TILE_WIDTH; ++m) { // Collaborative loading of Md and Nd tiles Mds[ty] [tx] = Md[Row*Width + (m*TILE_WIDTH + tx)]; Nds[ty][tx] = Nd[(m*TILE_WIDTH + ty)*Width + Col]; __syncthreads(); for (int k = 0; k < TILE_WIDTH; ++k) Pvalue += Mds[ty][k] * Nds[k][tx]; __syncthreads(); } Pd[Row*Width + Col] = Pvalue; //…
GPU ¡Programming ¡ 55 ¡
// Setup the execution configuration
dim3 dimBlock(TILE_WIDTH, TILE_WIDTH); dim3 dimGrid(Width / TILE_WIDTH, Width / TILE_WIDTH);
GPU ¡Programming ¡ 56 ¡
memory ¡for ¡256 ¡* ¡(2*16) ¡= ¡8,192 ¡mul/add ¡operaBons. ¡ ¡
GPU ¡Programming ¡ 57 ¡ Md Nd Pd Pdsub
TILE_WIDTH WIDTH WIDTH TILE_WIDTH TILE_WIDTH
bx tx
01 TILE_WIDTH-1 2 1 2
by ty
2 1 TILE_WIDTH-1 2 1
TILE_WIDTH TILE_WIDTH TILE_WIDTHE WIDTH WIDTH
m ¡ k ¡ bx ¡ by ¡ k ¡ m ¡
GPU ¡Programming ¡ 58 ¡
limiBng ¡factor ¡here ¡
per ¡thread ¡block, ¡allowing ¡only ¡up ¡to ¡two ¡thread ¡blocks ¡acBve ¡at ¡the ¡same ¡Bme ¡
GPU ¡Programming ¡ 59 ¡
accesses ¡as ¡it ¡has ¡banks ¡
result ¡in ¡a ¡bank ¡conflict ¡ ¡
Bank 15 Bank 7 Bank 6 Bank 5 Bank 4 Bank 3 Bank 2 Bank 1 Bank 0
GPU ¡Programming ¡ 60 ¡
stride ¡== ¡1 ¡
Bank 15 Bank 7 Bank 6 Bank 5 Bank 4 Bank 3 Bank 2 Bank 1 Bank 0 Thread 15 Thread 7 Thread 6 Thread 5 Thread 4 Thread 3 Thread 2 Thread 1 Thread 0 Bank 15 Bank 7 Bank 6 Bank 5 Bank 4 Bank 3 Bank 2 Bank 1 Bank 0 Thread 15 Thread 7 Thread 6 Thread 5 Thread 4 Thread 3 Thread 2 Thread 1 Thread 0
GPU ¡Programming ¡ 61 ¡
stride ¡== ¡2 ¡
stride ¡== ¡8 ¡
Thread 11 Thread 10 Thread 9 Thread 8 Thread 4 Thread 3 Thread 2 Thread 1 Thread 0 Bank 15 Bank 7 Bank 6 Bank 5 Bank 4 Bank 3 Bank 2 Bank 1 Bank 0 Thread 15 Thread 7 Thread 6 Thread 5 Thread 4 Thread 3 Thread 2 Thread 1 Thread 0 Bank 9 Bank 8 Bank 15 Bank 7 Bank 2 Bank 1 Bank 0 x8 x8
GPU ¡Programming ¡ 62 ¡
single ¡half-‑warp ¡
GPU ¡Programming ¡ 63 ¡
conflicts ¡
conflict ¡
bank ¡conflict ¡(broadcast) ¡
same ¡bank ¡
GPU ¡Programming ¡ 64 ¡
__shared__ float shared[256]; ¡ float foo = shared[baseIndex + s * threadIdx.x];
Bank 15 Bank 7 Bank 6 Bank 5 Bank 4 Bank 3 Bank 2 Bank 1 Bank 0 Thread 15 Thread 7 Thread 6 Thread 5 Thread 4 Thread 3 Thread 2 Thread 1 Thread 0 Bank 15 Bank 7 Bank 6 Bank 5 Bank 4 Bank 3 Bank 2 Bank 1 Bank 0 Thread 15 Thread 7 Thread 6 Thread 5 Thread 4 Thread 3 Thread 2 Thread 1 Thread 0
s=3 s=1
GPU ¡Programming ¡ 65 ¡
Bme ¡unBl ¡there ¡is ¡no ¡more. ¡
funcBon ¡of ¡thread ¡ID ¡
than ¡the ¡rest ¡of ¡the ¡threads ¡in ¡the ¡first ¡warp ¡
given ¡warp ¡follow ¡the ¡same ¡path ¡