CUDA
-
Upload
irene-dalton -
Category
Documents
-
view
67 -
download
0
description
Transcript of CUDA
![Page 1: CUDA](https://reader033.fdocument.pub/reader033/viewer/2022051416/56813320550346895d99f428/html5/thumbnails/1.jpg)
CUDAcudniejsze przyk|ady
![Page 2: CUDA](https://reader033.fdocument.pub/reader033/viewer/2022051416/56813320550346895d99f428/html5/thumbnails/2.jpg)
Agenda:
| CPU vs. GPU| Mnożenie macierzy – CPU| Mnożenie macierzy - GPU| Sploty
![Page 3: CUDA](https://reader033.fdocument.pub/reader033/viewer/2022051416/56813320550346895d99f428/html5/thumbnails/3.jpg)
Macierze – CPU vs. GPU
CPU:
| Mnożenie wykonywane w kolejnych iteracjach pętli.
| Przechodzimy przez pierwszy wiersz tabeli M i pierwszą kolumnę macierzy N, w pętli liczymy ich iloczyn skalarny i od razu zapisujemy go w macierzy wyjściowej.
GPU:
| paralelne wykonanie właściwego mnożenia macierzy
| każdy wątek wpisuje jeden element do macierzy wynikowej
Cdn...
![Page 4: CUDA](https://reader033.fdocument.pub/reader033/viewer/2022051416/56813320550346895d99f428/html5/thumbnails/4.jpg)
CPUIstotny dla zrozumienia różnicy pomiędzy tradycyjnym mnożeniem macierzy, a analogicznymi obliczeniami na GPU jest fakt linearnego adresowania macierzy w pierwszym przypadku.
Właśnie z linearnego adresowania macierzy wynika występujący w iteracji indeks postaci:
– i*Width+k. (i – numer wiersza; Width – wymiar n macierzy; k-numer kolumny)
Adresowanie linearne pokazano schematycznie na ilustracji:
![Page 5: CUDA](https://reader033.fdocument.pub/reader033/viewer/2022051416/56813320550346895d99f428/html5/thumbnails/5.jpg)
CPU
Jak widać, jest to podejście typowo sekwencyjne…
![Page 6: CUDA](https://reader033.fdocument.pub/reader033/viewer/2022051416/56813320550346895d99f428/html5/thumbnails/6.jpg)
GPUCoś ciekawszego, czyli:
![Page 7: CUDA](https://reader033.fdocument.pub/reader033/viewer/2022051416/56813320550346895d99f428/html5/thumbnails/7.jpg)
GPU - (C = AB)
Wersja najprostsza:Jest to wersja niezoptymalizowana. Każdy half warp oblicza jeden rząd tile’a C, polegając przy tym na jednym rzędzie z A i całym tile’u z B. W każdej iteracji pętli wszystkie wątki w half warpie czytają tę samą wartość z pamięci globalnej.
__global__ void simpleMultiply(float *a, float* b, float *c, int N){
int row = blockIdx.y * blockDim.y + threadIdx.y;int col = blockIdx.x * blockDim.x + threadIdx.x;float sum = 0.0f;
for (int i = 0; i < TILE_DIM; i++) {sum += a[row*TILE_DIM+i] * b[i*N+col];}
c[row*N+col] = sum;
}
![Page 8: CUDA](https://reader033.fdocument.pub/reader033/viewer/2022051416/56813320550346895d99f428/html5/thumbnails/8.jpg)
GPU - (C = AB)Wersja 2:Pierwszym z możliwych ulepszeń jest wykorzystanie pamięci współdzielonej. W drugiej wersji algorytmu wczytujemy tile z A do pamięci współdzielonej.
__global__ void coalescedMultiply(float *a, float* b, float *c,int N){
__shared__ float aTile[TILE_DIM][TILE_DIM];int row = blockIdx.y * blockDim.y + threadIdx.y;int col = blockIdx.x * blockDim.x + threadIdx.x;float sum = 0.0f;aTile[threadIdx.y][threadIdx.x] = a[row*TILE_DIM+threadIdx.x];for (int i = 0; i < TILE_DIM; i++) {sum += aTile[threadIdx.y][i]* b[i*N+col];}c[row*N+col] = sum;
}
![Page 9: CUDA](https://reader033.fdocument.pub/reader033/viewer/2022051416/56813320550346895d99f428/html5/thumbnails/9.jpg)
GPU - (C = AB)Wersja 3:Kolejnym możliwym ulepszeniem jest jednorazowe wczytywanie całego rzędu macierzy B do pamięci współdzielonej.
__global__ void sharedABMultiply(float *a, float* b, float *c,int N){__shared__ float aTile[TILE_DIM][TILE_DIM],bTile[TILE_DIM][TILE_DIM];int row = blockIdx.y * blockDim.y + threadIdx.y;int col = blockIdx.x * blockDim.x + threadIdx.x;float sum = 0.0f;aTile[threadIdx.y][threadIdx.x] = a[row*TILE_DIM+threadIdx.x];bTile[threadIdx.y][threadIdx.x] = b[threadIdx.y*N+col];__syncthreads();
for (int i = 0; i < TILE_DIM; i++) {sum += aTile[threadIdx.y][i]* bTile[i][threadIdx.x];}c[row*N+col] = sum;}
![Page 10: CUDA](https://reader033.fdocument.pub/reader033/viewer/2022051416/56813320550346895d99f428/html5/thumbnails/10.jpg)
Porównanie:Capability 1.1 - NVIDIA GeForce GT 9600M in a MacBookPro Laptop, 4 multiprocessors, 32 cores
Capability 1.2 - NVIDIA GeForce GT 330M in a MacBook ProLaptop, 6 multiprocessors, 48 cores
![Page 11: CUDA](https://reader033.fdocument.pub/reader033/viewer/2022051416/56813320550346895d99f428/html5/thumbnails/11.jpg)
Porównanie:Capability 1.3 - NVIDIA Tesla C1060 running in Earlham'scluster, 30 multiprocessors, 240 cores
Capability 2.0 - NVIDIA Tesla M2070 at the Texas AdvancedComputing Center, 14 multiprocessors, 448 cores
Matrix Multiplication with CUDA | A basic introductionto the CUDA programming modelRobert Hochberg
![Page 12: CUDA](https://reader033.fdocument.pub/reader033/viewer/2022051416/56813320550346895d99f428/html5/thumbnails/12.jpg)
Porównanie:
Matrix Multiplication with CUDA | NVIDIA CUDA C Best Practices Guide
Optymalizacja
NVIDIA GeForce
GTX 280(1.3)
NVIDIA GeForce
GTX 8800(1.0)
Bez optymalizacji 8.7 GBps 0.7 GBps
__shared__ float aTile 14.3 GBps 8.2 GBps
__shared__ float aTile, bTile 29.7 GBps 15.7 GBps
![Page 13: CUDA](https://reader033.fdocument.pub/reader033/viewer/2022051416/56813320550346895d99f428/html5/thumbnails/13.jpg)
Sploty
Przed zastosowaniem splotu: Po zastosowaniu splotu:
Splot znajduje szerokie zastosowanie w przetwarzaniu obrazów. Operacja splotu oblicza nową wartość piksela obrazu na podstawie wartości pikseli sąsiadujących.
![Page 14: CUDA](https://reader033.fdocument.pub/reader033/viewer/2022051416/56813320550346895d99f428/html5/thumbnails/14.jpg)
Sploty
Simple box blur: maska:(jak widać, maska ma efekt uśredniający)
Przed zastosowaniem splotu: Po zastosowaniu splotu:
![Page 15: CUDA](https://reader033.fdocument.pub/reader033/viewer/2022051416/56813320550346895d99f428/html5/thumbnails/15.jpg)
Sploty
Gaussian blur: maska:
Przed zastosowaniem splotu: Po zastosowaniu splotu:
![Page 16: CUDA](https://reader033.fdocument.pub/reader033/viewer/2022051416/56813320550346895d99f428/html5/thumbnails/16.jpg)
Sploty
Naiwna implementacja:W najprostszej wersji implementacji splotu każdy blok wątków przetwarza jeden blok obrazu. Każdy wątek generuje na wyjściu jeden piksel.
![Page 17: CUDA](https://reader033.fdocument.pub/reader033/viewer/2022051416/56813320550346895d99f428/html5/thumbnails/17.jpg)
Sploty
Brutalna konfrontacja:(z rzeczywistością)
Po zmodyfikowaniu naiwnego algorytmu zagadnienie zaczyna się komplikować…
Uwzględnienie w algorytmie „otoczki”, niezbędnej do przeliczenia brzegowych pikseli powoduje, że wątki odpowiedzialne wcześniej za wczytanie „otaczających” pikseli będą bezczynne przez cały czas przeliczania maski.
![Page 18: CUDA](https://reader033.fdocument.pub/reader033/viewer/2022051416/56813320550346895d99f428/html5/thumbnails/18.jpg)
Autorki| Urszula Jędrzejczak
| Katarzyna Ostrowicz
![Page 19: CUDA](https://reader033.fdocument.pub/reader033/viewer/2022051416/56813320550346895d99f428/html5/thumbnails/19.jpg)
KoniecBibliografia:| „CUDA by Example: An Introduction to General-Purpose GPU
Programming” Jason Sanders,Edward Kandrot
| „Programming Massively Parallel Processors: A Hands-on Approach”
| David B. Kirk, Wen-mei W. Hwu
| Dokumentacja NVIDIA: CUDA C Best Practices Guide Version 3.1 z 2010-05-28
| Image Convolution with CUDA Victor Podlozhnyuk[http://developer.download.nvidia.com/compute/cuda/1.1-Beta/x86_64_website/projects/convolutionSeparable/doc/convolutionSeparable.pdf]
| Matrix Multiplication with CUDA | A basic introduction to the CUDA programming modelRobert Hochberg [http://www.shodor.org/media/content//petascale/materials/UPModules/matrixMultiplication/moduleDocument.pdf]
| http://www.aishack.in/2010/08/image-convolution-examples/