Što je CUDA? Paralelno programiranje za GPU

CUDA je paralelna računalna platforma i model programiranja koji je razvila Nvidia za opće računanje na vlastitim GPU-ima (jedinice za obradu grafike). CUDA omogućuje programerima da ubrzaju računalno intenzivne aplikacije iskorištavanjem snage GPU-a za paralelni dio izračuna.

Iako su predloženi drugi API-ji za GPU-ove, poput OpenCL-a, i postoje konkurentni GPU-ovi drugih tvrtki, poput AMD-a, kombinacija CUDA i Nvidia GPU-a dominira u nekoliko područja primjene, uključujući duboko učenje, i temelj je za neke od njih. najbrža računala na svijetu.

Grafičke kartice vjerojatno su stare koliko i PC - to jest, ako IBM Monochrome Display Adapter iz 1981. godine smatrate grafičkom karticom. Do 1988. godine od ATI-ja ste mogli dobiti 16-bitnu 2D VGA Wonder karticu (tvrtku koju je na kraju kupio AMD). Do 1996. godine mogli ste kupiti 3D grafički akcelerator od 3dfx Interactive kako biste puncem mogli pokrenuti pucač u prvom licu Quake.

Također 1996. godine, Nvidia se počela pokušavati natjecati na tržištu 3D akceleratora sa slabim proizvodima, ali je naučila kako je išlo, te je 1999. predstavila uspješnu GeForce 256, prvu grafičku karticu koja se zvala GPU. U to je vrijeme glavni razlog postojanja GPU-a bio gaming. Tek kasnije ljudi su koristili GPU-ove za matematiku, znanost i inženjerstvo.

Podrijetlo CUDA

2003. godine tim istraživača pod vodstvom Iana Bucka predstavio je Brook, prvi široko usvojeni programski model koji je proširio C s paralelnim konstrukcijama podataka. Buck se kasnije pridružio Nvidiji i predvodio pokretanje CUDA-e 2006., prvog komercijalnog rješenja za opće namjene računala na GPU-ima.

OpenCL protiv CUDA

Apple i Khronos Group pokrenuli su CUDA konkurenta OpenCL 2009. godine, pokušavajući pružiti standard za heterogeno računanje koji nije ograničen na Intel / AMD CPU-ove s Nvidia GPU-ima. Iako OpenCL zvuči atraktivno zbog svoje općenitosti, nije se pokazao dobro kao CUDA na Nvidijinim grafičkim procesorima, a mnogi ga okviri za duboko učenje ili ne podržavaju ili podržavaju tek naknadno nakon što je objavljena njihova podrška za CUDA.

Poboljšanje izvedbe CUDA-e

CUDA je tijekom godina poboljšala i proširila svoj opseg, manje-više u korak s poboljšanim Nvidia GPU-ima. Od CUDA verzije 9.2, koristeći više GPU poslužitelja P100, možete ostvariti do 50 puta poboljšanja performansi u odnosu na CPU. V100 (nije prikazan na ovoj slici) još je tri puta brži za neka opterećenja. Prethodna generacija poslužiteljskih GPU-a, K80, nudila je poboljšanja performansi od 5x do 12x u odnosu na CPU.

Nvidia

Porast brzine s grafičkih procesora došao je u posljednje vrijeme za računalstvo visokih performansi. Povećanje izvedbe s jednim navojem s vremenom, za koje Mooreov zakon sugerira da će se udvostručiti svakih 18 mjeseci, usporilo se na 10 posto godišnje jer su proizvođači čipova naišli na fizička ograničenja, uključujući ograničenja veličine rezolucije maske čipa i prinosa čipa tijekom proizvodnog procesa i ograničenja topline na frekvencijama takta za vrijeme izvođenja.

Nvidia

CUDA aplikacijske domene

Nvidia

Grafički procesori CUDA i Nvidia usvojeni su u mnogim područjima koja trebaju visoke računske performanse s pomičnom zarezom, kao što je slikovito sažeto na gornjoj slici. Opsežniji popis uključuje:

  1. Računalne financije
  2. Modeliranje klime, vremena i oceana
  3. Znanost o podacima i analitika
  4. Dubinsko učenje i strojno učenje
  5. Obrana i obavještajni podaci
  6. Proizvodnja / AEC (arhitektura, inženjerstvo i graditeljstvo): CAD i CAE (uključujući računalnu dinamiku fluida, računsku strukturnu mehaniku, dizajn i vizualizaciju te elektroničku automatizaciju dizajna)
  7. Mediji i zabava (uključujući animaciju, modeliranje i prikazivanje; korekciju boja i upravljanje zrnom; sastavljanje; završna obrada i efekti; uređivanje; kodiranje i digitalna distribucija; grafike u eteru; ugrađeni, pregledni i stereo alati; i vremenske grafike)
  8. Medicinska slika
  9. Nafta i plin
  10. Istraživanje: Visoko obrazovanje i superračunarstvo (uključujući računalnu kemiju i biologiju, numeričku analitiku, fiziku i znanstvenu vizualizaciju)
  11. Sigurnost i osiguranje
  12. Alati i upravljanje

CUDA u dubokom učenju

Dubinsko učenje ima preveliku potrebu za brzinom računanja. Primjerice, za osposobljavanje modela za Google Translate 2016. timovi Google Brain i Google Translate izveli su stotine jednotjednih TensorFlow trčanja pomoću GPU-ova; u tu su svrhu kupili 2.000 GPU-a poslužiteljskog nivoa od Nvidije. Bez GPU-a, tim treningima trebali bi mjeseci, a ne tjedan dana da se konvergiraju. Za produkcijsku primjenu tih prijevodnih modela TensorFlow, Google je koristio novi prilagođeni procesorski čip, TPU (tensor processing unit).

Uz TensorFlow, mnogi drugi DL okviri oslanjaju se na CUDA za podršku GPU-a, uključujući Caffe2, CNTK, Databricks, H2O.ai, Keras, MXNet, PyTorch, Theano i Torch. U većini slučajeva koriste CuDNN knjižnicu za proračune duboke neuronske mreže. Ta je knjižnica toliko važna za obuku okvira za duboko učenje da svi okviri koji koriste datu verziju cuDNN-a imaju u osnovi iste brojeve izvedbe za ekvivalentne slučajeve upotrebe. Kada se CUDA i cuDNN poboljšavaju od verzije do verzije, svi okviri za dubinsko učenje koji se ažuriraju na novu verziju vide poboljšanje performansi. Gdje se izvedba razlikuje od okvira do okvira, to je koliko dobro se skaliraju na više GPU-a i više čvorova.

CUDA programiranje

Nvidia

CUDA Toolkit

CUDA Toolkit uključuje knjižnice, alate za otklanjanje pogrešaka i optimizaciju, kompajler, dokumentaciju i runtime knjižnicu za postavljanje vaših aplikacija. Sadrži komponente koje podržavaju duboko učenje, linearnu algebru, obradu signala i paralelne algoritme. Općenito, CUDA knjižnice podržavaju sve obitelji Nvidijinih grafičkih procesora, ali najbolje se izvode na najnovijoj generaciji, poput V100, koji može biti 3 puta brži od P100 za radna opterećenja s dubokim učenjem. Korištenje jedne ili više knjižnica najlakši je način iskorištavanja GPU-a, pod uvjetom da su algoritmi koji su vam potrebni implementirani u odgovarajuću knjižnicu.

Nvidia

CUDA knjižnice za duboko učenje

U sferi dubokog učenja postoje tri glavne GPU-ubrzane knjižnice: cuDNN, koju sam ranije spomenuo kao GPU komponentu za većinu okvira za duboko učenje otvorenog koda; TensorRT, koji je Nvidijin optimizator dubokog učenja i izvedbe visokih performansi; i DeepStream, biblioteka video zaključaka. TensorRT vam pomaže optimizirati modele neuronske mreže, kalibrirati za nižu preciznost s velikom točnošću i rasporediti obučene modele u oblake, podatkovne centre, ugrađene sustave ili platforme automobilskih proizvoda.

Nvidia

CUDA linearne algebre i matematičke knjižnice

Linearna algebra podupire tenzorska izračunavanja i stoga duboko učenje. BLAS (Basic Linear Algebra Subprograms), zbirka matričnih algoritama implementiranih u Fortranu 1989. godine, od tada se koriste od strane znanstvenika i inženjera. cuBLAS je verzija BLAS-a ubrzana GPU-om i način rada s matricnom aritmetikom s GPU-ima s najboljim performansama. cuBLAS pretpostavlja da su matrice guste; cuSPARSE obrađuje rijetke matrice.

Nvidia

CUDA knjižnice za obradu signala

Brza Fourierova transformacija (FFT) jedan je od osnovnih algoritama koji se koristi za obradu signala; pretvara signal (poput audio valnog oblika) u spektar frekvencija. cuFFT je FFT ubrzan GPU-om.

Kodeci, koristeći standarde poput H.264, kodiraju / komprimiraju i dekodiraju / dekomprimiraju videozapise za prijenos i prikaz. Nvidia Video Codec SDK ubrzava ovaj proces s grafičkim procesorima.

Nvidia

CUDA biblioteke paralelnih algoritama

Sve tri knjižnice za paralelne algoritme imaju različite svrhe. NCCL (Nvidia Collective Communications Library) namijenjen je skaliranju aplikacija na više GPU-ova i čvorova; nvGRAPH je za paralelnu analitiku grafova; i Thrust je knjižnica predložaka C ++ za CUDA koja se temelji na knjižnici C ++ standardnih predložaka. Potisak pruža bogatu zbirku paralelnih primitiva podataka poput skeniranja, sortiranja i smanjenja.

Nvidia

CUDA naspram performansi CPU-a

U nekim slučajevima možete koristiti padajuće CUDA funkcije umjesto ekvivalentnih CPU funkcija. Na primjer, GEMM-ove rutine množenja matrica iz BLAS-a mogu se zamijeniti verzijama GPU-a jednostavnim povezivanjem s NVBLAS knjižnicom:

Nvidia

Osnove programiranja CUDA

Ako ne možete pronaći rutine knjižnice CUDA za ubrzavanje programa, morat ćete se okušati u programiranju CUDA niske razine. To je sada puno lakše nego što je bilo kad sam prvi put probao krajem 2000-ih. Između ostalih razloga, postoji lakša sintaksa i dostupni su bolji razvojni alati. Moja jedina dvojba je da su na MacOS-u najnoviji CUDA kompajler i najnoviji C ++ kompajler (iz Xcodea) rijetko sinkronizirani. Treba preuzeti starije alate naredbenog retka s Applea i prebaciti se na njih pomoću xcode-selectCUDA koda za kompajliranje i povezivanje.

Na primjer, razmotrite ovu jednostavnu C / C ++ rutinu za dodavanje dva polja:

void dodaj (int n, float * x, float * y)

{  

       za (int i = 0; i <n; i ++)      

             y [i] = x [i] + y [i];

}

Možete ga pretvoriti u kernel koji će se izvoditi na GPU-u dodavanjem __global__ključne riječi u deklaraciju i pozvati kernel koristeći sintaksu trostruke zagrade:

dodaj << >> (N, x, y);

Također morate promijeniti svoje malloc/ newi free/ deletepozive u cudaMallocManagedi cudaFreetako da dodjeljujete prostor na GPU-u. Napokon, trebate pričekati da se završi izračun GPU-a prije nego što upotrijebite rezultate na CPU-u, što možete postići cudaDeviceSynchronize.

Gornji trostruki nosač koristi jedan blok navoja i jedan navoj. Trenutni Nvidijini grafički procesori mogu obraditi mnoge blokove i niti. Na primjer, Tesla P100 GPU zasnovan na Pascal GPU Arhitekturi ima 56 strujnih multiprocesora (SM), od kojih svaki može podržati do 2048 aktivnih niti.

Kôd jezgre trebat će znati svoj indeks blokova i niti kako bi pronašao njegov pomak u proslijeđenim nizovima. Paralelizirani kernel često koristi grid-stride petlju, kao što je sljedeće:

__globalno__

void dodaj (int n, float * x, float * y)

{

   int indeks = blockIdx.x * blockDim.x + threadIdx.x;

   int korak = blockDim.x * gridDim.x;

   za (int i = indeks; i <n; i + = iskorak)

     y [i] = x [i] + y [i];

}

Ako pogledate uzorke u CUDA Toolkitu, vidjet ćete da treba razmotriti više od osnova koje sam gore obradio. Na primjer, neki pozivi funkcije CUDA moraju biti umotani u checkCudaErrors()pozive. Također, u mnogim će se slučajevima najbrži kôd koristiti knjižnicama, kao što je cuBLASdodjela hosta i memorije uređaja te kopiranje matrica naprijed-natrag.

Ukratko, svoje aplikacije možete ubrzati GPU-ima na mnogim razinama. Možete napisati CUDA kod; možete nazvati CUDA knjižnice; a možete koristiti programe koji već podržavaju CUDA.