GPU radionica

Luko Gjenero SRCE

30. Siječnja 2013. GPU?

30. Siječnja 2013. Povijest video igara • Najstariji zapisi

• 25 Siječanj 1947 • Thomas T. Goldsmith, Jr. • Estle Ray Mann • "cathode ray tube amusement device"

30. Siječnja 2013. Povijest video igara

• Prvi pokušaji zabave

30. Siječnja 2013. Povijest video igara

• Prva UNIX aplikacija

30. Siječnja 2013. Povijest video igara • Igraći uređaji – 1970te

30. Siječnja 2013. Povijest video igara

• Space Invaders

30. Siječnja 2013. Povijest video igara

• Prvi 3D pokušaji

30. Siječnja 2013. Povijest video igara

• 1990te – flat

30. Siječnja 2013. Povijest video igara

• 1990te –

30. Siječnja 2013. Povijest video igara

• 1990te – 3D akeceleratori

30. Siječnja 2013. Povijest video igara

30. Siječnja 2013. Danas

30. Siječnja 2013. Povijest GPU

->

30. Siječnja 2013. 3D grafika

• Renderiranje – Proces kreiranja slike iz modela • Vertex – Vrh poligona (najčešće trokuta) u modelu • Pixel – Najmanji element ekrana koji se može adresirati

30. Siječnja 2013. 3D grafika

• Kako od modela do slike

-1.069812 1.643532 -0.283202 -1.523047 1.586146 -0.444300 -1.728016 1.344536 -0.656323 -1.815546 1.037839 -0.906679 -1.810727 0.682244 -1.158979 -1.788165 0.455138 -1.301172 -1.764957 0.177459 -1.467339 -1.701842 -0.448811 -1.830056 -> -1.672400 -1.013893 -2.108265 -1.626917 -1.431036 -2.280596 -1.703426 -1.507439 -1.654671 -1.813526 -1.568119 -0.884709 -1.934581 -1.572616 -0.164067 -2.085154 -1.548759 0.671415 -2.223489 -1.516222 1.435532 …

30. Siječnja 2013. Povijest GPU

• Prije GPU -> CPU – Slijedno računanje • Količina operacija – Scena sa 100 000 trokuta – Svaki trokut rasterizira se na prosječno 100 pixela – 10 izvora svjetlosti – 4 ciklusa po izvoru – => 400 000 000 ciklusa

30. Siječnja 2013. Povijest GPU

• Razvoj počeo u 1980-tima • 1983 Intel napravio iSBX 275 • 1985 Commodore Amiga prvo osobno računalo koje je standardno imalo ugrađen GPU • 1987 IBM napravio 8514 kao prvu grafičku karticu sa “fixed-function” 2D primitivima

30. Siječnja 2013. Fixed function Pipeline • Prihvaća grafičke naredbe i podatke od CPU

30. Siječnja 2013. Fixed function Pipeline

• Prihvaća podatke o trokutima • Pretvara podatke u oblik koji HW razumije • Sprema pripremljene podatke u cache

30. Siječnja 2013. Fixed function Pipeline • Vertex transform and lighting • Postavlja vrijednosti za pojedini vertex

30. Siječnja 2013. Fixed function Pipeline

• Računa bridove trokuta te postavlja jednadžbe za interpolaciju vertx vrijednosti na pixele koje obuhvaća trokut

30. Siječnja 2013. Fixed function Pipeline

• Određuje koji pixel pripada kojem trokutu • Interpolira vrijednosti za svaki pojedini pixel

30. Siječnja 2013. Fixed function Pipeline

• Određuje konačnu boju za svaki pixel u trokutu

30. Siječnja 2013. Fixed function Pipeline

• Raster operation • Izvršava raster operacije koje računaju miješanje boje trokuta koji se preklapaju ovisno o prozirnosti i metodi anitaliasinga

30. Siječnja 2013. Fixed function Pipeline

• Frame buffer interface • Vrši upravljanje pisanjem i čitanjem iz memorije

30. Siječnja 2013. 3D akceleratori

• 1996 – – Voodoo chipset • Mystique • S3 ViRGE • ATI Rage • 3D API – OpenGL – DirecX

30. Siječnja 2013. Programirljivi GPU

• 2001 – NVIDIA – Omogućila programerima pristup setu instrukcija u fazi transformacija vertexa i modela osvjetljenja (VS/T & L) – Kasnije prošireno na fazu određivanja konačne boje svakog pixela u trokutu ()

30. Siječnja 2013. Programirljivi GPU

30. Siječnja 2013. Programirljivi GPU

• Moguće rješavati probleme korištenjem GPU – Podaci zadani preko tekstura i vertex buffera • Problem adresiranja – Izlaz je 2D slika – Limitirani set instrukcija • Nema operacija sa cijelim brojevima • Nema logičkih operacija

30. Siječnja 2013. Programirljivi GPU

• 2006 NVIDIA GeForce 8800 – Mapira različite faze grafičkog procesiranja na unificirano polje procesora – CUDA

30. Siječnja 2013. CUDA GPU

30. Siječnja 2013. CUDA

30. Siječnja 2013. CUDA

30. Siječnja 2013. CUDA

30. Siječnja 2013. CUDA

30. Siječnja 2013. CUDA

30. Siječnja 2013. HW - Fermi

• Do 16 SM na GPU • Svaki SM može imati 32 jezgre – Izvršava posao u SIMT načinu – Single Instruction Multiple Thread • 16 SM x 32 jezgre = 512 jezgri

30. Siječnja 2013. HW - Fermi

• Warp – 32 dretve – Instrukcije se zadaju po warpu • Ukoliko neki operand u warpu nije spreman za izvršavanje – Mijenja se kontekst warpa - > izvršava se drugi warp – Smanjuje se “idle” vrijeme HW – Mijenjanje konteksta mora biti iznimno brzo

30. Siječnja 2013. HW - Fermi

• Mijenjanje konteksta – Svi resursi unutar bloka su aktivni za vrijeme izvođenja cijelog bloka • Registri • Dijeljena memorija – Brzo mijenjane konteksta (warpa) je moguće baš zato jer se registri i dijeljena memorija ne moraju stalno spremati i vraćati u aktivno stanje prilikom svake izmjene konteksta • Cilj – dovoljno transakcija da se memorijska sabirnica zasiti • Fermi omogućuje do 48 warpa na SM – Znači max. 1536 dretvi po SM

30. Siječnja 2013. HW - Fermi

• Zauzetost SM-a (Occupancy) – Broj warpova / Max. broj warpova • Resursi za blok su ograničeni – Previše resursa po dretvi smanjuje broj warpova u bloku – Broj registara – Količina dijeljene memorije – Veličina bloka

30. Siječnja 2013. HW - Fermi • Registri – Prevođenje s zastavicom --ptxas-options=-v – 32K registara po SM • Primjer 1 – Dretva zauzima 20 registra (+1 implicitni) – Moguće 32K / 21 -> 1560 dretvi • > 1536 -> zauzetost od 100% ili1.0 • Primjer 2 – Dretva zauzima 63 registra po dretvi (+1 implicitni) – Moguće 32K / 64 -> 512 dretvi • < 1536 -> zauzetost od 33.3% ili 0.333 • Max broj registara: --maxrregcount

30. Siječnja 2013. HW - Fermi

• Dijeljena memorija – Prevođenje s zastavicom --ptxas-options=-v – 16K ili 48K po SM • Primjer 1 – 48K dijeljene memorije, 32 byte po dretvi – 48K / 32 -> 1536 dretvi – Zauzetost = 100% • Primjer 2 – 16K dijeljene memorije, 32 byte po dretvi – 16K / 32 -> 512 dretvi – Zauzetost = 33.3%

30. Siječnja 2013. HW – Fermi

• Veličina bloka – SM može imati do 8 aktivnih blokova

Veličina bloka Broj dretvi po SM Zauzetost 32 256 16.7 % 64 512 33.3 % 128 1024 66.6 % 192 1536 100 % 256 2048 100 %

30. Siječnja 2013. HW – Fermi

• Preporuke – 66 % zauzetosti – 128-256 veličina bloka (višekratnik 32 - warp) – CUDA_Occupancy_calculator.xls • Dolazi sa Toolkitom • Excel sa formulama za izračunavanje zauzetosti

30. Siječnja 2013. CUDA

• Programska sučelja – C/C++ – FORTRAN – OpenACC – OpenCL • Biblioteke – cuFFT – cuBLAS – cuSPARSE

30. Siječnja 2013. CUDA

• Instalacija – https://developer.nvidia.com/cuda-downloads • Podržani HW – https://developer.nvidia.com/cuda-gpus

30. Siječnja 2013. CUDA

• /usr/lib64/nvidia • /usr/lib64/cuda/ – bin – lib64 – Include • /usr/share/cuda

30. Siječnja 2013. CUDA

• Ispis uređaja na PCI priključcima lspci | grep -i nvidia

• Ispis podataka o CUDA uređajima nvidia-smi -q

30. Siječnja 2013. CUDA

• Environment varijable – CUDA_VISIBLE_DEVICES • Definicija uređaja koje API može koristiti • export CUDA_VISIBLE_DEVICES=0 – CUDA_LAUNCH_BLOCKING • Omogućuje blokirajući poziv kernel funkcije • export CUDA_LAUNCH_BLOCKING=1

30. Siječnja 2013. CRO-NGI

• 36 x M2075 – Single 1030 Gflops – Double 515 Gflops – 150 GB/s – 6 GB – 448 CUDA jezgre

30. Siječnja 2013. Isabella

• 1 x Tesla S2050 – 4 GPU – Single 4.13 Tflops – Double 2 Tflops – 148 GB/s – 12 GB – 448 CUDA jezgri po GPU

30. Siječnja 2013. CUDA

• CUDA C API – Definicija funkcija (kernela) koje se izvršavaju na GPU – Rezervacija i oslobađanje memorije na GPU – Komunikacija RAM <-> GPU – Sinkronizacija kernela

30. Siječnja 2013. CUDA kernel

// Kernel definition __global__ void KernelName( float* A, float* B, float* C) { int i = threadIdx.x; C[i] = A[i] + B[i]; }

30. Siječnja 2013. CUDA kernel

• threadIdx – Id dretve unutar bloka – 1D, 2D ili 3D vektor • blockDim – dimenzije bloka dretvi – 1D, 2D ili 3D vektor • blockIdx – Id bloka unutar grida – 1D, 2D ili 3D vektor

30. Siječnja 2013. CUDA funkcije

● Postoje 3 vrste funkcija

– __global__ – __device__ – __host__

30. Siječnja 2013. CUDA varijable

● Područje dosutpnosti

– __device__ – __shared__ – __constant__ – __restrict__

30. Siječnja 2013. CUDA tipovi podataka

• integer i floating point tipovi, signed i unsigned verzije • struct tipovi podataka • vektorski tipovi podataka • float2, float3, float4, int2, int3, … • C++ tipovi podataka nisu ugrađeni – Bolje izbjegavati – string -> char*

30. Siječnja 2013. CUDA built-in funkcije

● Osnovne matematiče operacije

– + - / * pow sqrt ...

● Logaritamske

– log, log2, log10, log1p, exp, exp2, exp10, expm1

● Trigonometrijske

– sin, cos, tan, asin, acos, atan, sinh, cosh, ...

● Funkcije vezane za teksture i površine

● Atomic funkcije

30. Siječnja 2013. CUDA API

● Include path

– /usr/lib64/cuda/include

● Library path

– /usr/lib64/cuda/lib64

– /usr/lib64/nvidia/

● Headers

– #include

– #include

● 30. Siječnja 2013. CUDA API

● Device

– cudaGetDeviceCount – cudaSetDevice – cudaGetDeviceProperties – cudaChooseDevice

30. Siječnja 2013. CUDA API

● Memory

– cudaMalloc – cudaMallocHost – cudaMemcpy – cudaFree – cudaFreeHost

30. Siječnja 2013. CUDA API

● Kernel KernelName<<< blocksPerGrid, threadsPerBlock, SharedMemorySize, StreamReference >>> (params, ...);

30. Siječnja 2013. www.srce.hr [email protected]

30. Siječnja 2013.