Programmering

Hva er CUDA? Parallell programmering for GPUer

CUDA er en parallell databehandlingsplattform og programmeringsmodell utviklet av Nvidia for generell databehandling på egne GPUer (grafikkbehandlingsenheter). CUDA gjør det mulig for utviklere å øke hastigheten på beregningskrevende applikasjoner ved å utnytte kraften til GPUer for den parallelliserbare delen av beregningen.

Mens det har vært andre foreslåtte API-er for GPUer, som OpenCL, og det er konkurransedyktige GPUer fra andre selskaper, som AMD, dominerer kombinasjonen av CUDA og Nvidia GPUer flere applikasjonsområder, inkludert dyp læring, og er et fundament for noen av verdens raskeste datamaskiner.

Grafikkort er uten tvil like gamle som PC-en - det vil si hvis du ser på IBMs monokrome skjermadapter fra 1981 som et grafikkort. I 1988 kunne du få et 16-biters 2D VGA Wonder-kort fra ATI (selskapet som til slutt ble kjøpt opp av AMD). Innen 1996 kunne du kjøpe en 3D-grafikkakselerator fra 3dfx Interactive slik at du kunne kjøre første person-skytteren Quake i full fart.

Også i 1996 begynte Nvidia å prøve å konkurrere i 3D-akseleratormarkedet med svake produkter, men lærte etter hvert, og i 1999 introduserte den vellykkede GeForce 256, det første grafikkortet som ble kalt GPU. På den tiden var hovedårsaken til å ha en GPU for spill. Først senere brukte folk GPUer for matematikk, naturfag og ingeniørfag.

Opprinnelsen til CUDA

I 2003 avduket et team av forskere ledet av Ian Buck Brook, den første vidt adopterte programmeringsmodellen som utvidet C med dataparallelle konstruksjoner. Buck kom senere til Nvidia og ledet lanseringen av CUDA i 2006, den første kommersielle løsningen for generell databehandling på GPUer.

OpenCL vs. CUDA

CUDA-konkurrent OpenCL ble lansert av Apple og Khronos Group i 2009, i et forsøk på å gi en standard for heterogen databehandling som ikke var begrenset til Intel / AMD-prosessorer med Nvidia-GPUer. Selv om OpenCL høres attraktivt ut på grunn av allmenheten, har det ikke fungert like bra som CUDA på Nvidia-GPUer, og mange dype læringsrammer støtter det ikke eller støtter det bare som en ettertanke når deres CUDA-støtte er utgitt.

CUDA ytelse boost

CUDA har forbedret og utvidet omfanget gjennom årene, mer eller mindre i lås med forbedrede Nvidia-GPUer. Fra og med CUDA versjon 9.2, ved å bruke flere P100-server-GPUer, kan du oppnå opptil 50 ganger ytelsesforbedringer over CPUer. V100 (ikke vist i denne figuren) er en annen 3x raskere for noen belastninger. Den forrige generasjonen server-GPUer, K80, tilbød 5x til 12x ytelsesforbedringer i forhold til CPUer.

Nvidia

Hastighetsøkningen fra GPUer har kommet på kort tid for høyytelses databehandling. Den single-threaded ytelsesøkningen av CPUer over tid, som Moores lov foreslo ville fordobles hver 18. måned, har bremset ned til 10 prosent per år ettersom produsentene av brikkene møtte fysiske grenser, inkludert størrelsesbegrensninger på chipmaskeoppløsning og chiputbytte under produksjonsprosessen og varmegrenser på klokkefrekvenser ved kjøretid.

Nvidia

CUDA-applikasjonsdomener

Nvidia

CUDA og Nvidia GPUer har blitt tatt i bruk i mange områder som trenger høy flytende punkt-beregningsytelse, som oppsummert i bildet i bildet ovenfor. En mer omfattende liste inkluderer:

  1. Beregningsøkonomi
  2. Klima, vær og havmodellering
  3. Datavitenskap og analyse
  4. Dyp læring og maskinlæring
  5. Forsvar og etterretning
  6. Produksjon / AEC (arkitektur, ingeniørfag og konstruksjon): CAD og CAE (inkludert beregningsvæskedynamikk, beregningsmessig strukturell mekanikk, design og visualisering og elektronisk designautomatisering)
  7. Media og underholdning (inkludert animasjon, modellering og gjengivelse; fargekorrigering og kornhåndtering; komposisjon; etterbehandling og effekter; redigering; koding og digital distribusjon; on-air grafikk; on-set, gjennomgang og stereoverktøy; og værgrafikk)
  8. Medisinsk bildebehandling
  9. Olje og gass
  10. Forskning: Høyere utdanning og superdatamaskin (inkludert beregningskjemi og biologi, numerisk analyse, fysikk og vitenskapelig visualisering)
  11. Trygghet og sikkerhet
  12. Verktøy og ledelse

CUDA i dyp læring

Dyp læring har et stort behov for beregningshastighet. For eksempel, for å trene modellene for Google Translate i 2016, gjorde Google Brain og Google Translate-teamene hundrevis av en ukes TensorFlow-kjøringer ved hjelp av GPUer; de hadde kjøpt 2000 server-GPUer fra Nvidia for formålet. Uten GPUer ville det ha tatt flere måneder enn en uke å trene disse treningsløpene. For produksjonsutplassering av disse TensorFlow-oversettelsesmodellene brukte Google en ny tilpasset prosesseringsbrikke, TPU (tensor prosesseringsenhet).

I tillegg til TensorFlow er mange andre DL-rammer avhengige av CUDA for GPU-støtte, inkludert Caffe2, CNTK, Databricks, H2O.ai, Keras, MXNet, PyTorch, Theano og Torch. I de fleste tilfeller bruker de cuDNN-biblioteket til dype nevrale nettverksberegninger. Dette biblioteket er så viktig for opplæringen av de dype læringsrammene at alle rammeverkene som bruker en gitt versjon av cuDNN, i det vesentlige har samme ytelsestall for tilsvarende brukstilfeller. Når CUDA og cuDNN forbedrer seg fra versjon til versjon, ser alle dype læringsrammer som oppdateres til den nye versjonen, resultatgevinstene. Hvor ytelsen har en tendens til å variere fra ramme til rammeverk, er hvor godt de skaleres til flere GPUer og flere noder.

CUDA programmering

Nvidia

CUDA verktøysett

CUDA Toolkit inkluderer biblioteker, feilsøkings- og optimaliseringsverktøy, en kompilator, dokumentasjon og et kjøretidsbibliotek for å distribuere applikasjonene dine. Den har komponenter som støtter dyp læring, lineær algebra, signalbehandling og parallelle algoritmer. Generelt støtter CUDA-biblioteker alle familier med Nvidia GPUer, men klarer seg best på den nyeste generasjonen, for eksempel V100, som kan være 3 ganger raskere enn P100 for arbeidsbelastning for dyp læring. Å bruke ett eller flere biblioteker er den enkleste måten å dra nytte av GPUer, så lenge algoritmene du trenger er implementert i riktig bibliotek.

Nvidia

CUDA biblioteker for dyp læring

I den dype læringssfæren er det tre store GPU-akselererte biblioteker: cuDNN, som jeg nevnte tidligere som GPU-komponenten for de fleste open source dyp læringsrammer; TensorRT, som er Nvidias høykvalitets optimaliseringsoptimering for dyp læring og kjøretid; og DeepStream, et videoinferensebibliotek. TensorRT hjelper deg med å optimalisere nevrale nettverksmodeller, kalibrere for lavere presisjon med høy nøyaktighet og distribuere de trente modellene til skyer, datasentre, innebygde systemer eller bilproduktplattformer.

Nvidia

CUDA lineære algebra- og mattebiblioteker

Lineær algebra underbygger tensorberegninger og derfor dyp læring. BLAS (Basic Linear Algebra Subprograms), en samling matrisealgoritmer implementert i Fortran i 1989, har blitt brukt siden da av forskere og ingeniører. cuBLAS er en GPU-akselerert versjon av BLAS, og den høyest ytende måten å gjøre matrisearitmetikk med GPUer. cuBLAS antar at matriser er tette; cuSPARSE håndterer sparsomme matriser.

Nvidia

CUDA signalbehandlingsbiblioteker

Den raske Fourier-transformasjonen (FFT) er en av de grunnleggende algoritmene som brukes til signalbehandling; det gjør et signal (for eksempel en lydbølgeform) til et frekvensspekter. cuFFT er en GPU-akselerert FFT.

Kodeker bruker standarder som H.264, koder / komprimerer og dekoder / dekomprimerer video for overføring og visning. Nvidia Video Codec SDK fremskynder denne prosessen med GPUer.

Nvidia

CUDA parallelle algoritmebiblioteker

De tre bibliotekene for parallelle algoritmer har alle forskjellige formål. NCCL (Nvidia Collective Communications Library) er for skalering av apper på tvers av flere GPUer og noder; nvGRAPH er for parallell grafanalyse; og Thrust er et C ++ malbibliotek for CUDA basert på C ++ Standardmalbibliotek. Thrust gir en rik samling av data parallelle primitiver som skanning, sortering og reduksjon.

Nvidia

CUDA vs. CPU-ytelse

I noen tilfeller kan du bruke drop-in CUDA-funksjoner i stedet for tilsvarende CPU-funksjoner. For eksempel kan GEMM-matriks-multiplikasjonsrutinene fra BLAS erstattes av GPU-versjoner ved å koble til NVBLAS-biblioteket:

Nvidia

Grunnleggende om CUDA-programmering

Hvis du ikke finner CUDA-bibliotekrutiner for å akselerere programmene dine, må du prøve deg på CUDA-programmering på lavt nivå. Det er mye lettere nå enn det var da jeg først prøvde det på slutten av 2000-tallet. Blant andre grunner er det lettere syntaks, og det er bedre utviklingsverktøy tilgjengelig. Min eneste uenighet er at den siste CUDA kompilatoren og den siste C ++ kompilatoren (fra Xcode) på MacOS er sjelden synkronisert. Man må laste ned eldre kommandolinjeverktøy fra Apple og bytte til dem ved hjelp av xcode-velg for å få CUDA-koden til å kompilere og koble til.

Tenk for eksempel på denne enkle C / C ++ rutinen for å legge til to matriser:

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

{  

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

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

}

Du kan gjøre den om til en kjerne som kjører på GPU ved å legge til __global__ nøkkelord til erklæringen, og ring kjernen ved å bruke trippelbrakett-syntaksen:

legg til << >> (N, x, y);

Du må også endre din malloc/ny og gratis/slett ringer til cudaMallocManaged og cudaFree slik at du tildeler plass på GPUen. Til slutt må du vente på at en GPU-beregning skal fullføres før du bruker resultatene på CPUen, som du kan oppnå med cudaDeviceSynchronize.

Trippelbraketten ovenfor bruker en trådblokk og en tråd. Nåværende Nvidia GPUer kan håndtere mange blokker og tråder. For eksempel har en Tesla P100 GPU basert på Pascal GPU Architecture 56 Streaming Multiprocessors (SMs), som hver kan støtte opptil 2048 aktive tråder.

Kjernekoden må kjenne blokk- og trådindeksen for å finne forskyvningen i de passerte matriser. Den parallelliserte kjernen bruker ofte en rutenett-skritt sløyfe, for eksempel følgende:

__global__

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

{

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

int skritt = blockDim.x * gridDim.x;

for (int i = indeks; i <n; i + = skritt)

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

}

Hvis du ser på eksemplene i CUDA Toolkit, vil du se at det er mer å vurdere enn det grunnleggende jeg dekket ovenfor. For eksempel må noen CUDA-funksjonssamtaler pakkes inn checkCudaErrors () ringer. I mange tilfeller vil den raskeste koden bruke biblioteker som cuBLAS sammen med tildelinger av verts- og enhetsminne og kopiering av matriser frem og tilbake.

Oppsummert kan du akselerere appene dine med GPUer på mange nivåer. Du kan skrive CUDA-kode; du kan ringe CUDA-biblioteker; og du kan bruke applikasjoner som allerede støtter CUDA.

$config[zx-auto] not found$config[zx-overlay] not found