CUDA je vzporedna računalniška platforma in programski model, ki ga je razvila Nvidia za splošno računalništvo na lastnih grafičnih procesorjih (enotah za obdelavo grafike). CUDA razvijalcem omogoča pospeševanje računalniško intenzivnih aplikacij z izkoriščanjem moči grafičnih procesorjev za vzporedni del izračuna.
Čeprav so bili za GPU predlagani tudi drugi API-ji, kot je OpenCL, in obstajajo konkurenčni grafični procesorji drugih podjetij, kot je AMD, kombinacija grafičnih procesorjev CUDA in Nvidia prevladuje na več področjih uporabe, vključno z globokim učenjem, in je temelj za nekatere najhitrejši računalniki na svetu.
Grafične kartice so verjetno stare toliko kot osebni računalnik - torej če menite, da je IBM Monochrome Display Adapter iz leta 1981 grafična kartica. Do leta 1988 lahko pri ATI (podjetje, ki ga je sčasoma kupila AMD) dobite 16-bitno 2D VGA Wonder kartico. Do leta 1996 ste lahko pri 3dfx Interactive kupili pospeševalnik 3D-grafike, tako da ste lahko s polno hitrostjo zagnali prvoosebni strelec Quake.
Tudi leta 1996 je Nvidia začela poskušati konkurirati na trgu 3D pospeševalnikov s šibkimi izdelki, vendar se je naučila med letom in leta 1999 predstavila uspešno GeForce 256, prvo grafično kartico, imenovano GPU. Takrat je bil glavni razlog za GPU igralništvo. Šele pozneje so ljudje uporabili grafične procesorje za matematiko, znanost in tehniko.
Izvor CUDA
Leta 2003 je skupina raziskovalcev pod vodstvom Iana Bucka predstavila Brook, prvi široko sprejeti programski model, ki je razširil C s podatkovno vzporednimi konstrukti. Buck se je kasneje pridružil družbi Nvidia in leta 2006 vodil predstavitev CUDA, prve komercialne rešitve za splošno uporabo na GPU.
OpenCL proti CUDA
Konkurenta CUDA OpenCL sta Apple in Khronos Group lansirala leta 2009, da bi zagotovila standard za heterogeno računalništvo, ki ni bil omejen na procesorje Intel / AMD z grafičnimi procesorji Nvidia. Čeprav OpenCL zaradi svoje splošnosti zveni privlačno, ni nastopil tako dobro kot CUDA na grafičnih procesorjih Nvidia, številni okviri za poglobljeno učenje pa ga ne podpirajo ali podpirajo le vnaprej, ko je bila objavljena njihova podpora za CUDA.
Povečanje zmogljivosti CUDA
CUDA je skozi leta izboljšal in razširil svoj obseg, bolj ali manj v koraku z izboljšanimi grafičnimi procesorji Nvidia. Od različice CUDA 9.2 lahko z uporabo več strežniških grafičnih procesorjev P100 dosežete do 50-kratno izboljšanje učinkovitosti CPU-jev. V100 (na tej sliki ni prikazan) je pri nekaterih obremenitvah še trikrat hitrejši. Prejšnja generacija strežniških grafičnih procesorjev, K80, je ponudila 5- do 12-kratno izboljšanje zmogljivosti v primerjavi s CPU-ji.

Pospeševanje hitrosti iz grafičnih procesorjev je prišlo v kratkem času za visokozmogljivo računalništvo. Povečanje zmogljivosti enonitnih procesorjev s časom, za katero Moore zakon predlaga, da bi se podvojilo vsakih 18 mesecev, se je upočasnilo na 10 odstotkov na leto, saj so proizvajalci čipov naleteli na fizične omejitve, vključno z omejitvami velikosti ločljivosti maske čipa in izkoristkom čipa med proizvodnim procesom in omejitve toplote na frekvencah ur med izvajanjem.

Domene aplikacij CUDA

Grafični procesorji CUDA in Nvidia so bili sprejeti na številnih področjih, ki potrebujejo visoko računalniško zmogljivost s plavajočo vejico, kot je slikovito povzeto na zgornji sliki. Izčrpnejši seznam vključuje:
- Računalniške finance
- Modeliranje podnebja, vremena in oceanov
- Podatkovna znanost in analitika
- Poglobljeno učenje in strojno učenje
- Obramba in obveščevalni podatki
- Proizvodnja / AEC (arhitektura, inženiring in gradbeništvo): CAD in CAE (vključno z računsko dinamiko tekočin, računsko mehaniko struktur, načrtovanjem in vizualizacijo ter elektronsko avtomatizacijo načrtovanja)
- Mediji in zabava (vključno z animacijami, modeliranjem in upodabljanjem; barvna korekcija in upravljanje zrn; sestavljanje; dodelava in učinki; urejanje; kodiranje in digitalna distribucija; žična grafika; vgrajena, pregledna in stereo orodja; in vremenska grafika)
- Medicinsko slikanje
- Nafta in plin
- Raziskave: visokošolsko izobraževanje in superračunalništvo (vključno z računalniško kemijo in biologijo, numerično analitiko, fiziko in znanstveno vizualizacijo)
- Varnost
- Orodja in upravljanje
CUDA v globokem učenju
Poglobljeno učenje ima preveliko potrebo po računalniški hitrosti. Na primer, za usposabljanje modelov za Google Translate leta 2016 sta ekipi Google Brain in Google Translate izvedli na stotine enotedenskih tekov TensorFlow z uporabo grafičnih procesorjev; za ta namen so od Nvidie kupili 2.000 grafičnih procesorjev strežniškega razreda. Brez grafičnih procesorjev bi ti treningi trajali mesece in ne en teden, da bi se zbližali. Za proizvodno uvajanje teh prevajalskih modelov TensorFlow je Google uporabil nov čip za obdelavo po meri, TPU (procesorska enota za tenzor).
Poleg TensorFlowa se številni drugi ogrodji DL za podporo GPU zanašajo na CUDA, vključno s Caffe2, CNTK, Databricks, H2O.ai, Keras, MXNet, PyTorch, Theano in Torch. V večini primerov za izračune globokih nevronskih mrež uporabljajo knjižnico cuDNN. Ta knjižnica je tako pomembna za usposabljanje ogrodja globokega učenja, da imajo vsi okviri, ki uporabljajo določeno različico cuDNN, v bistvu enake številke učinkovitosti za enakovredne primere uporabe. Ko se CUDA in cuDNN izboljšujeta od različice do različice, vsi okviri za poglobljeno učenje, ki se posodobijo na novo različico, vidijo povečanje učinkovitosti. Kadar se uspešnost razlikuje od okvira do ogrodja, je v tem, kako dobro se razširijo na več grafičnih procesorjev in več vozlišč.
Programiranje CUDA

Nabor orodij CUDA
Nabor orodij CUDA vključuje knjižnice, orodja za odpravljanje napak in optimizacijo, prevajalnik, dokumentacijo in izvajalno knjižnico za razmestitev aplikacij. Vsebuje komponente, ki podpirajo globoko učenje, linearno algebro, obdelavo signalov in vzporedne algoritme. Na splošno knjižnice CUDA podpirajo vse družine grafičnih procesorjev Nvidia, vendar se najbolje obnesejo pri najnovejši generaciji, kot je V100, ki je lahko 3-krat hitrejša od P100 za delovne obremenitve pri globokem učenju. Uporaba ene ali več knjižnic je najlažji način, da izkoristite prednosti grafičnih procesorjev, če so algoritmi, ki jih potrebujete, implementirani v ustrezno knjižnico.

CUDA knjižnice za globoko učenje
Na področju globokega učenja obstajajo tri glavne knjižnice, pospešene z GPU: cuDNN, ki sem jo prej omenil kot komponento GPU za večino odprtokodnih okvirov za globoko učenje; TensorRT, ki je Nvidijin visokozmogljivi optimizator in izvajalno sklepanje za globoko učenje; in DeepStream, knjižnica video sklepov. TensorRT vam pomaga optimizirati modele nevronskih omrežij, umeriti za nižjo natančnost z visoko natančnostjo in usposobljene modele razporediti v oblake, podatkovne centre, vdelane sisteme ali platforme avtomobilskih izdelkov.

CUDA linearne algebre in matematične knjižnice
Linearna algebra podpira tenzorske izračune in s tem globoko učenje. Od takrat znanstveniki in inženirji uporabljajo BLAS (Basic Linear Algebra Subprograms), zbirko matričnih algoritmov, uvedenih v Fortranu leta 1989. cuBLAS je različica BLAS, pospešena z GPU, in najučinkovitejši način za matrično aritmetiko z grafičnimi procesorji. cuBLAS predpostavlja, da so matrike goste; cuSPARSE obravnava redke matrike.

Knjižnice za obdelavo signalov CUDA
Hitra Fourierjeva transformacija (FFT) je eden izmed osnovnih algoritmov za obdelavo signalov; signal (na primer zvočno valovno obliko) spremeni v spekter frekvenc. cuFFT je FFT, pospešen z GPU.
Kodeki, ki uporabljajo standarde, kot je H.264, kodirajo / stisnejo in dekodirajo / dekomprimirajo video za prenos in prikaz. SDK za Nvidia Video Codec pospeši ta postopek z grafičnimi procesorji.

Knjižnice vzporednih algoritmov CUDA
Vse tri knjižnice za vzporedne algoritme imajo različne namene. NCCL (Nvidia Collective Communications Library) je namenjena skaliranju aplikacij na več grafičnih procesorjih in vozliščih; nvGRAPH je namenjen vzporedni analitiki grafov; in Thrust je knjižnica predlog C ++ za CUDA, ki temelji na standardni knjižnici predlog C ++. Potisk zagotavlja bogato zbirko podatkov vzporednih primitivov, kot so skeniranje, razvrščanje in zmanjšanje.

CUDA v primerjavi z zmogljivostjo CPU
V nekaterih primerih lahko namesto enakovrednih funkcij CPU uporabite spuščene funkcije CUDA. Na primer, rutine množenja matrik GEMM iz BLAS lahko nadomestite z različicami GPU preprosto s povezavo na knjižnico NVBLAS:

Osnove programiranja CUDA
Če ne morete najti rutin knjižnice CUDA za pospešitev programov, se boste morali preizkusiti v programiranju CUDA na nizki ravni. Zdaj je to veliko lažje, kot je bilo, ko sem prvič poskusil konec 2000-ih. Med drugimi razlogi je lažja skladnja in na voljo so boljša razvojna orodja. Moje edino dvomljivo je, da sta v MacOS-u najnovejši prevajalnik CUDA in najnovejši prevajalnik C ++ (iz Xcode) redko sinhronizirana. Iz Apple je treba prenesti starejša orodja ukazne vrstice in z njimi preklopiti nanje xcode-select
pridobiti kodo CUDA za sestavljanje in povezovanje.
Na primer, upoštevajte to preprosto rutino C / C ++, da dodate dva polja:
void add (int n, float * x, float * y){
za (int i = 0; i <n; i ++)
y [i] = x [i] + y [i];
}
Lahko ga spremenite v jedro, ki se bo izvajalo na GPU, tako da dodate __global__
ključno besedo v deklaracijo in s sintakso trojnega oklepaja pokličite jedro:
dodaj << >> (N, x, y);
Spremeniti morate tudi svojega malloc
/novo
in prost
/izbriši
klici na cudaMallocManaged
in cudaFree
tako da dodelite prostor na GPU. Na koncu morate počakati, da se zaključi izračun GPU, preden uporabite rezultate na CPU, s katerimi lahko dosežete cudaDeviceSynchronize
.
Zgornji trojni nosilec uporablja en blok niti in en navoj. Trenutni grafični procesorji Nvidia lahko obvladajo veliko blokov in niti. Na primer, GPU Tesla P100, ki temelji na arhitekturi Pascal GPU, ima 56 pretočnih večprocesorjev (SM), od katerih lahko vsak podpira do 2048 aktivnih niti.
Koda jedra bo morala poznati svoj indeks blokov in niti, da bo našla odmik v posredovanih nizih. V vzporednem jedru se pogosto uporablja mreža-korak zanko, na primer naslednje:
__global__void add (int n, float * x, float * y)
{
int index = blockIdx.x * blockDim.x + threadIdx.x;
int stride = blockDim.x * gridDim.x;
za (int i = indeks; i <n; i + = korak)
y [i] = x [i] + y [i];
}
Če si ogledate vzorce v zbirki orodij CUDA, boste videli, da je treba upoštevati več kot osnove, ki sem jih obravnaval zgoraj. Na primer, nekatere klice funkcij CUDA je treba zaviti checkCudaErrors ()
klici. Tudi v mnogih primerih bodo najhitreje kode uporabljale knjižnice, kot je cuBLAS
skupaj z dodeljevanjem pomnilnika gostitelja in naprave ter kopiranjem matrik naprej in nazaj.
Če povzamemo, lahko svoje aplikacije pospešite z grafičnimi procesorji na več ravneh. Lahko napišete kodo CUDA; lahko pokličete knjižnice CUDA; in lahko uporabljate aplikacije, ki že podpirajo CUDA.