Technologia GPGPU na przykładzie środowiska CUDA Instytut Fizyki Teoretycznej Uniwersytet Wrocławski
Plan prezentacji CPU Architektura CPU GPU Architektura GPU Architektura CUDA Istniejące środowiska programowania GPU Programowanie GPU Typy danych i jądro Krata, bloki, wątki, pamięć Przykłady HelloWorld w wersji wielowątkowej Problem N ciał bez oddziaływania O(N) ProblemNoddziałującychciałO(N 2 ) Na Koniec Na Deser
Plan prezentacji CPU Architektura CPU GPU Architektura GPU Architektura CUDA Istniejące środowiska programowania GPU Programowanie GPU Typy danych i jądro Krata, bloki, wątki, pamięć Przykłady HelloWorld w wersji wielowątkowej Problem N ciał bez oddziaływania O(N) ProblemNoddziałującychciałO(N 2 ) Na Koniec Na Deser
Architektura CPU Plan prezentacji CPU Architektura CPU GPU Architektura GPU Architektura CUDA Istniejące środowiska programowania GPU Programowanie GPU Typy danych i jądro Krata, bloki, wątki, pamięć Przykłady HelloWorld w wersji wielowątkowej Problem N ciał bez oddziaływania O(N) ProblemNoddziałującychciałO(N 2 ) Na Koniec Na Deser
Architektura CPU Architektura CPU CPU = Central Processing Unit ALU- jednostka arytmetyczno-logiczna Rejestry- integralna pamięć CPU(dane) IR- rejestr instrukcji(rozkazów procesora) PC-licznikprogramu(miejscewliście rozkazów procesora)
Architektura CPU Schemat działania CPU CPUbyłzzałożeniaprocesoremsekwencyjnym 1 : fetch- pobieranie rozkazu do wykonania(pc) decode- przekładanie rozkazu na operacje elementarne CPU execute- wykonanie operacji(alu) writeback- zapisanie wyniku(np. do rejestrów) 1 http:en.wikipedia.orgwikicentralprocessingunit
Architektura CPU Obliczenia równoległe, a CPU: Obliczenia równoległe, a CPU: poziom instrukcji(instruction pipelining, superscalar pipeline) - wykorzystanie opóźnień w sekwencji podstawowej procesora poziom wątków(multiple Instructions-Multiple Data) - od kilku procesorów(1960 r.) do wielordzeniowości(2001 r.) poziom danych(single Instruction-Multiple Data)- wektoryzacja CPU, nadaje się do specjalnej klasy problemów
Plan prezentacji CPU Architektura CPU GPU Architektura GPU Architektura CUDA Istniejące środowiska programowania GPU Programowanie GPU Typy danych i jądro Krata, bloki, wątki, pamięć Przykłady HelloWorld w wersji wielowątkowej Problem N ciał bez oddziaływania O(N) ProblemNoddziałującychciałO(N 2 ) Na Koniec Na Deser
Architektura GPU Plan prezentacji CPU Architektura CPU GPU Architektura GPU Architektura CUDA Istniejące środowiska programowania GPU Programowanie GPU Typy danych i jądro Krata, bloki, wątki, pamięć Przykłady HelloWorld w wersji wielowątkowej Problem N ciał bez oddziaływania O(N) ProblemNoddziałującychciałO(N 2 ) Na Koniec Na Deser
Architektura GPU Potok graficzny(1) Źródło: The Cg Tutorial, nvidia
Architektura GPU Potok graficzny(2) Źródło: The Cg Tutorial, nvidia
Architektura GPU GPU- Graphics Processor Unit Procesor GPU został zoptymalizowany pod kątem wykonywania elementów potoku graficznego: te same operacje na ogromnej liczbie elementów architektura SIMD(Single Instruction-Multiple Data) tranzystory używane do wykonywania ogromnej ilości operacji zmiennoprzecinkowych programowalne jednostki cieniujące(vertex/pixel shaders) języki programowania wysokiego poziomu(cg, HLSL, GLSL)
Architektura GPU Porównanie architektury GPU i CPU Źródło: nvidia CUDA, Programming Guide 2.2, nvidia
Architektura GPU Wydajność(1) Źródło: nvidia CUDA, Programming Guide 2.2, nvidia
Architektura GPU Wydajność(2) Źródło: nvidia CUDA, Programming Guide 2.2, nvidia
Plan prezentacji CPU Architektura CPU GPU Architektura GPU Architektura CUDA Istniejące środowiska programowania GPU Programowanie GPU Typy danych i jądro Krata, bloki, wątki, pamięć Przykłady HelloWorld w wersji wielowątkowej Problem N ciał bez oddziaływania O(N) ProblemNoddziałującychciałO(N 2 ) Na Koniec Na Deser
Istniejące środowiska programowania GPU Plan prezentacji CPU Architektura CPU GPU Architektura GPU Architektura CUDA Istniejące środowiska programowania GPU Programowanie GPU Typy danych i jądro Krata, bloki, wątki, pamięć Przykłady HelloWorld w wersji wielowątkowej Problem N ciał bez oddziaływania O(N) ProblemNoddziałującychciałO(N 2 ) Na Koniec Na Deser
Istniejące środowiska programowania GPU Środowiska Początki GPGPU, to obliczenia z użyciem programowalnych jednostek cieniujących Aktualnie istnieją dwa kompleksowe środowiska do programowania procesorów GPU(ATI, nvidia) Równolegle powstaje OpenCL- otwarty standard do obliczeń równoległych(grupa Khronos)
Istniejące środowiska programowania GPU Co to właściwie jest CUDA? CUDA, Compute Unified Device Architecture: język wysokiego poziomu oparty na c interfejs programowania aplikacji dedykowany kompilator(nvcc) model pamięci W przyszłości CUDA będzie obsługiwana z poziomu dowolnego języka(źródło: nvidia CUDA, Programming Guide 2.2, nvidia).
Istniejące środowiska programowania GPU Model pamięci w architekturze CUDA W CUDA wyróżniamy kilka rodzajów pamięci na których operuje GPU: shared memory(16kb) texture cache constant cache device memory(gb)
Plan prezentacji CPU Architektura CPU GPU Architektura GPU Architektura CUDA Istniejące środowiska programowania GPU Programowanie GPU Typy danych i jądro Krata, bloki, wątki, pamięć Przykłady HelloWorld w wersji wielowątkowej Problem N ciał bez oddziaływania O(N) ProblemNoddziałującychciałO(N 2 ) Na Koniec Na Deser
Typy danych i jądro Plan prezentacji CPU Architektura CPU GPU Architektura GPU Architektura CUDA Istniejące środowiska programowania GPU Programowanie GPU Typy danych i jądro Krata, bloki, wątki, pamięć Przykłady HelloWorld w wersji wielowątkowej Problem N ciał bez oddziaływania O(N) ProblemNoddziałującychciałO(N 2 ) Na Koniec Na Deser
Typy danych i jądro Programowanie w CUDA(1) nowe typy danych wektorowych: char1, char2, char3, char4, int1, uint1, int2, uint2, int3, uint3, int4, uint4, float1, float2, float3, float4, double1, double2, dim3(+ wiele innych)
Typy danych i jądro Programowanie w CUDA(2) przykład dla float3: 1 ÐÓ Ø Û Ñ ÐÓ Ø ¼º½ ¾º¾ º¼µ 2 ÐÓ Ø ÛºÜ ÛºÞ // a = 4.1 typy wektorowe nie posiadają przeciążonych operatorów arytmetycznych można próbować tak(prędkość) 1 Ú ÐÓ Ø ÓÔ Ö ØÓÖ ÓÒ Ø ÐÓ Ø ² 2 ÓÒ Ø ÐÓ Ø ² µ 3 ß 4 Ö ØÙÖÒ Ñ ÐÓ Ø ºÜ ºÜ ºÝ ºÝ ºÞ ºÞµ 5 Ð w praktyce należy bardzo starannie dbać o dostęp do pamięci!
Typy danych i jądro Jądro, deklaracja i wywołanie(1) wcudaprogramydlagputojądra(ang.kernel) kodjąderumieszczasięwplikach.cu Jądro(ang.kernel)deklarujesiępodobniejakfunkcjewc dodajemy słowo kluczowe opisującego poziom z jakiego można wywołać jądro(z funkcji CPU, z innego jądra itp.)
Typy danych i jądro Jądro, deklaracja i wywołanie(2) przykład deklaracji: 1 ÐÓ Ð ÚÓ ÓËÓÑ Ø Ò ÇÒ Ú ºººµ 2 ß 3 ººº 4 Ð gdzie: global kompilowane dla GPU, wywoływane przez CPU device kompilowane dla GPU, wywoływane przez GPU host kompilowane dla CPU, wywoływane przez CPU
Typy danych i jądro Jądro, deklaracja i wywołanie(3) Jądrowywołujesiępodobniejakfunkcjewjęzykuc dodatkowo deklaruje się ilość bloków w kracie i ilość wątków na blok używając nawiasów: 1 ººº ººº przykład wywołania: 1 ÒØ ÐÓ Ë Þ ½¾ 2 ÒØ Ò ÐÓ Æ» ÐÓ Ë Þ 3 Æ ± ÐÓ Ë Þ ¼ ¼ ½µ 4 5 ÓËÓÑ Ø Ò ÇÒ Ú Ò ÐÓ ÐÓ Ë Þ ºººµ
Krata, bloki, wątki, pamięć Plan prezentacji CPU Architektura CPU GPU Architektura GPU Architektura CUDA Istniejące środowiska programowania GPU Programowanie GPU Typy danych i jądro Krata, bloki, wątki, pamięć Przykłady HelloWorld w wersji wielowątkowej Problem N ciał bez oddziaływania O(N) ProblemNoddziałującychciałO(N 2 ) Na Koniec Na Deser
Krata, bloki, wątki, pamięć Krata, bloki, wątki... 1 ÓËÓÑ Ø Ò ÇÒ Ú Ò ÐÓ ÐÓ Ë Þ ºººµ tworzy kratę(grid) o nblocks blokach(blocks) blocksize wątków każdy Przykład nblocks = dim3(3,2,1); blocksize = dim3(4,3,1); Źródło: nvidia CUDA, Programming Guide 2.2, nvidia
Krata, bloki, wątki, pamięć Deklarowanie zmiennych, pamięć(1) stałewpamięcigpu,np. 1 ÓÒ Ø ÒØ ÐÓ Ø Ö Ú ØÝ ß¼ ¹½º¼ ¼Ð zmienne w pamięci globalnej karty, np. 1 Ú ÐÓ Ø Ú ÐÓ ØÝ ß¼ ¼ ¼Ð pamięć współdzielona na wątki w bloku 1 Ö ÐÓ Ø Ø Ð Æ dostęp do zmiennych typu device z CPU, przykład: 1 ÐÓ Ø Ú Ð Ó Ø 2 ÓÒ Ø Ö ÝÑ ÓÐ Ú ÐÓ ØÝ 3 Ù Å ÑÔÝ ÖÓÑËÝÑ ÓÐ Ú Ð Ó Ø ÝÑ ÓÐ 4 Þ Ó ÐÓ Ø µ ¼ Ù Å ÑÔÝ Ú ÌÓÀÓ Øµ
Krata, bloki, wątki, pamięć Alokacja pamięci i kopiowanie(cpu GPU) CPU 1 ÐÓ Ø ÐÓ Ø µñ ÐÐÓ Þ µ GPU 1 ÐÓ Ø 2 Ù Å ÐÐÓ ÚÓ µ ² Þ µ Kopiowanie CPU GPU 1 Ù Å ÑÔÝ Þ Ù Å ÑÔÝÀÓ ØÌÓ Ú µ Kopiowanie CPU GPU 1 Ù Å ÑÔÝ Þ Ù Å ÑÔÝ Ú ÌÓÀÓ Øµ
Plan prezentacji CPU Architektura CPU GPU Architektura GPU Architektura CUDA Istniejące środowiska programowania GPU Programowanie GPU Typy danych i jądro Krata, bloki, wątki, pamięć Przykłady HelloWorld w wersji wielowątkowej Problem N ciał bez oddziaływania O(N) ProblemNoddziałującychciałO(N 2 ) Na Koniec Na Deser
HelloWorld w wersji wielowątkowej Plan prezentacji CPU Architektura CPU GPU Architektura GPU Architektura CUDA Istniejące środowiska programowania GPU Programowanie GPU Typy danych i jądro Krata, bloki, wątki, pamięć Przykłady HelloWorld w wersji wielowątkowej Problem N ciał bez oddziaływania O(N) ProblemNoddziałującychciałO(N 2 ) Na Koniec Na Deser
HelloWorld w wersji wielowątkowej Hello World 1 #include <stdio.h> 2 #include <cuda.h> 3 4 device char napis_device[14]; 5 6 global void helloworldondevice(void) 7 { 8 napis_device[0] = H ; 9 napis_device[1] = e ; 10... 11 napis_device[12] = \n ; 12 napis_device[13] = 0; 13 } 14 15 int main(void) 16 { 17 helloworldondevice <<< 1, 1 >>>(); 18 cudathreadsynchronize(); 19 20 char napis_host[14]; 21 const char *symbol= napis device ; 22 cudamemcpyfromsymbol (napis_host, symbol, sizeof(char)*13, 0, cudamemcpydevicetohost); 23 24 printf( %s,napis_host); 25 } Wynik: Hello World! wpisane przez GPU.
HelloWorld w wersji wielowątkowej Hello World w wersji wielowątkowej Hello World! w wersji wielowątkowej: funkcjonalność jądra bez zmian podzielmy zadania na osobne rdzenie niech każda literka zostanie wpisana przez osobny rdzeń! (Wspólnie z Pawłem Czubińskim)
HelloWorld w wersji wielowątkowej Hello World w wersji wielowątkowej Jądrorozbijamyna14blokówpo1wątkukażdy: 1 ÐÐÓÏÓÖÐ ÇÒ Ú ½ ½ µ
HelloWorld w wersji wielowątkowej Hello World 1 2 device char napis_device[14]; 3 constant device char hw[]= HelloWorld!\n ; 4 5 global void helloworldondevice(void) 6 { 7 int idx = blockidx.x; 8 napis_device[idx] = hw[idx]; 9 } 10 11 int main(void) 12 { 13 helloworldondevice <<< 14, 1 >>>(); 14 cudathreadsynchronize(); 15... 16 } Wynik: Hello World! wpisane przez GPU wielowątkowo! Każda literka przez inny rdzeń(jeśli zasoby były wolne).
Problem N ciał bez oddziaływania O(N) Plan prezentacji CPU Architektura CPU GPU Architektura GPU Architektura CUDA Istniejące środowiska programowania GPU Programowanie GPU Typy danych i jądro Krata, bloki, wątki, pamięć Przykłady HelloWorld w wersji wielowątkowej Problem N ciał bez oddziaływania O(N) ProblemNoddziałującychciałO(N 2 ) Na Koniec Na Deser
Problem N ciał bez oddziaływania O(N) N nieoddziałujących ciał, problem O(N) N nieoddziałujących punktów materialnych grawitacjag = (0,g y,0) przyciąganie do wybranego punktu pętla obliczeniowa: 1. wyliczenie sił 2. całkowanie równań ruchu małooperacjinaodczytzpamięci! złożoność problemu rośnie liniowo- O(N)
Problem N ciał bez oddziaływania O(N) Rozwiązanie 1. CPU 1 2 for(inti=0;i<n;i++) 3 { 4 5 DIST=sqrt((_ATR.x-pos[i].x)*(_ATR.x-pos[i].x) 6 +(_ATR.y-pos[i].y)*(_ATR.y-pos[i].y)); 7 8 if(dist) 9 { 10 ATRF.x=KD*((_ATR.x-pos[i].x))/DIST; 11 ATRF.y=KD*((_ATR.y-pos[i].y))/DIST; 12 } 13 14 vel[i].x=vel[i].x+(g.x+atrf.x)*dt; 15 vel[i].y=vel[i].y+(g.y+atrf.y)*dt; 16 17 pos[i].x=pos[i].x+vel[i].x*dt; 18 pos[i].y=pos[i].y+vel[i].y*dt; 19 20 if(pos[i].x >1){pos[i].x = 1; vel[i].x =-vel[i].x;} 21 if(pos[i].y >1){pos[i].y = 1; vel[i].y =-vel[i].y;} 22 if(pos[i].x <-1){pos[i].x =-1; vel[i].x =-vel[i].x;} 23 if(pos[i].y <-1){pos[i].y =-1; vel[i].y =-vel[i].y;} 24 25 } x2 dostęp do pamięci!
Problem N ciał bez oddziaływania O(N) Rozwiązanie 2. GPU, float3 1 global void movepartondevice 2 (float3* posvbo, float3 *vel,...) 3 { 4 int idx = blockidx.x*blockdim.x + threadidx.x; 5 6 float3 posidx; 7 float3 velidx; 8 9 (...) 10 11 if(idx<_n) 12 { 13 posidx = posvbo[idx]; 14 velidx = vel[idx]; 15 16 //------------------------------------- 17 // Tu: pętla analogiczna z CPU, z zamianą 18 // pos[i]-> posidx 19 // vel[i]-> velidx 20 //------------------------------------- 21 22 posvbo[idx] = posidx; 23 vel[idx] = velidx; 24 } 25 } x2 dostęp do pamięci!
Problem N ciał bez oddziaływania O(N) Dostęp zwarty do pamięci(coalesced)
Problem N ciał bez oddziaływania O(N) Rozwiązanie 3. GPU, float4 1 global void movepartondevice 2 (float4* posvbo, float4 *vel,...) 3 { 4 int idx = blockidx.x*blockdim.x + threadidx.x; 5 6 float4 posidx; 7 float4 velidx; 8 9 (...) 10 11 if(idx<_n) 12 { 13 posidx = posvbo[idx]; 14 velidx = vel[idx]; 15 16 //------------------------------------- 17 // Tu: pętla analogiczna z CPU, z zamianą 18 // pos[i]-> posidx 19 // vel[i]-> velidx 20 //------------------------------------- 21 22 posvbo[idx] = posidx; 23 vel[idx] = velidx; 24 } 25 } x10 rząd wielkości!
Problem N ciał bez oddziaływania O(N) Problem O(N), wizualizacja w OpenGL, GPU vs CPU 0.5 miliona punktów wizualizacja w czasie rzeczywistym OpenGL GL Utility Toolkit(GLUT) Vertex Buffer Object(VBO) [run]
Problem N ciał bez oddziaływania O(N) Problem O(N) w działaniu, porównanie t[ms] 1 0.1 0.01 CPU GPU3 GPU4 złożoność liniowa GPU pamięć karty > CPU pamięć na płycie. dostępzwarty x10! 0.001 10 5 10 6 10 7 N
ProblemNoddziałującychciałO(N 2 ) Plan prezentacji CPU Architektura CPU GPU Architektura GPU Architektura CUDA Istniejące środowiska programowania GPU Programowanie GPU Typy danych i jądro Krata, bloki, wątki, pamięć Przykłady HelloWorld w wersji wielowątkowej Problem N ciał bez oddziaływania O(N) ProblemNoddziałującychciałO(N 2 ) Na Koniec Na Deser
ProblemNoddziałującychciałO(N 2 ) Noddziałującychciał,problemO(N 2 ) N mas oddziałujących grawitacyjnie oddziaływanie każdy z każdym pętla obliczeniowa: 1. wyliczenie sił(podwójna) 2. całkowanie równań ruchu
ProblemNoddziałującychciałO(N 2 ) Rozwiązanie 1. CPU, N=32000 1 2 (...) 3 4 for(inti=0;i<n;i++) 5 for(intj=0;j<n;j++) 6 { 7 n.x=pos[j].x-pos[i].x; 8 n.y=pos[j].y-pos[i].y; 9 10 DIST=sqrt(n.x*n.x+n.y*n.y+EPS2); 11 12 //fg=n*g*m1m2/r**3 13 14 forc[i].x +=(n.x* BIGG/ DIST*DIST*DIST); 15 forc[i].y +=(n.y* BIGG/ DIST*DIST*DIST); 16 17 } 18 19 (...)
ProblemNoddziałującychciałO(N 2 ) Rozwiązanie 2. GPU, N=32000 1 global void moveparticlesondevice 2 (float4* posvbo, float4 *vel,...) 3 { 4 int idx = blockidx.x*blockdim.x + threadidx.x; 5 (...) 6 if(idx<_n) 7 { 8 posidx = posvbo[idx]; 9 10 forc.x = 0; 11 forc.y = 0; 12 13 for(intj=0;j<_n;j++) 14 { 15 //fg=n*g*m1m2/r**3 16 // między posidx, a posvbo[j] 17 // analogicznie jak w kodzie CPU 18 (...) 19 } 20 } 21 22 (...) 23 }
ProblemNoddziałującychciałO(N 2 ) Algorytm n ciał z pamięcią shared Efektywny algorytm N ciał dla CUDA: Lars Nyland, Mark Harris, Jan Prins Fast N-Body Simulation with CUDA GPUGems3 algorytm n ciał z wykorzystaniem pamięci współdzielonej wkażdymwątkuwyznaczanychjestnsił p-ilośćwątkówwbloku każdy wątek wykonuje p razy pętlę liczącą N/p oddziaływań te N/p oddziaływań obliczanych jest w pamięci shared mapowanie wątek/blok- miejsce w pamięci
ProblemNoddziałującychciałO(N 2 ) Rozwiązanie 3. GPU- pamięć współdzielona, N=32000 1000 naive (loop) shared mem t CPU / t GPU 100 10 1 10 2 10 3 10 4 10 5 x100! 2rzędyróżnicy! N
ProblemNoddziałującychciałO(N 2 ) ProblemO(N 2 ),wizualizacjawopengl,gpuvscpu 5835 punktów wizualizacja w czasie rzeczywistym OpenGL GL Utility Toolkit(GLUT) Vertex Buffer Object(VBO) [run-cpu] [run-gpu] [(GPU+CPU)]
Plan prezentacji CPU Architektura CPU GPU Architektura GPU Architektura CUDA Istniejące środowiska programowania GPU Programowanie GPU Typy danych i jądro Krata, bloki, wątki, pamięć Przykłady HelloWorld w wersji wielowątkowej Problem N ciał bez oddziaływania O(N) ProblemNoddziałującychciałO(N 2 ) Na Koniec Na Deser
Na zakończenie Krótkie podsumowanie: optymalizacja dostępu do pamięci- kluczowa potrzebna gruntowna rekonstrukcja algorytmów pamięćtypushared-16kbrejestrów(!) narzut pracy ogromny, ale.. zysk również Przyszłość? GTX300- ponoć czeka nas zmiana architektury (!) Uwaga: W trakcie seminarium nie powiedzieliśmy nic o compute capabilities, operacjach atomowych, synchronizacji wątków, buforach wierzchołków i pikseli, teksturach, rozplątywaniu pętli, konfliktach dostępu do pamięci, zwojach (warpach) wątków itd.. Źródło: nvidia CUDA, Programming Guide 2.2, nvidia
Żródła http://4.bp.blogspot.com/ hqgvfa7rye4/skai1b2qgli/aaaaaaaabd4/q5mhupffhca/s400/hun+sen+shaking+ http://www.ipipan.gda.pl/wiesiek/pjwstk/08-09/ark/wyklad-03.pdf http://http.developer.nvidia.com/cgtutorial/cgtutorialchapter01.html http://arstechnica.com/hardware/reviews/2008/06/nvidia-geforce-gx2-review.ars nvidiacuda,programmingguide2.2,nvidia Wikipedia ZbigniewKoza, CUDAnaTwoimbiurku,czylisłówkilkanatematComputeUnifiedDeviceArchitecture, Wykład
Na Deser Plan prezentacji CPU Architektura CPU GPU Architektura GPU Architektura CUDA Istniejące środowiska programowania GPU Programowanie GPU Typy danych i jądro Krata, bloki, wątki, pamięć Przykłady HelloWorld w wersji wielowątkowej Problem N ciał bez oddziaływania O(N) ProblemNoddziałującychciałO(N 2 ) Na Koniec Na Deser
Na Deser Na deser prosty model materii granulowanej: N.Bell,Y.YuandP.J.Mucha, Particle-Based Simulation of Granular Materials, Eurographics/ACM SIGGRAPH(2005) oddziaływania sprężyste między masami CUDA, 4096 ziaren, [run]
Na Deser Koniec Dziękuję za uwagę