Wat is CUDA? Parallelle programmering voor GPU's

CUDA is een parallel computerplatform en programmeermodel ontwikkeld door Nvidia voor algemeen computergebruik op zijn eigen GPU's (grafische verwerkingseenheden). CUDA stelt ontwikkelaars in staat om rekenintensieve applicaties te versnellen door de kracht van GPU's te gebruiken voor het parallelliseerbare deel van de berekening.

Hoewel er andere voorgestelde API's voor GPU's zijn, zoals OpenCL, en er concurrerende GPU's zijn van andere bedrijven, zoals AMD, domineert de combinatie van CUDA- en Nvidia-GPU's verschillende toepassingsgebieden, waaronder deep learning, en vormt het een basis voor sommige van de snelste computers ter wereld.

Grafische kaarten zijn misschien wel zo oud als de pc, dat wil zeggen, als je de IBM Monochrome Display Adapter uit 1981 als een grafische kaart beschouwt. In 1988 kon je een 16-bits 2D VGA Wonder-kaart krijgen van ATI (het bedrijf dat uiteindelijk door AMD werd overgenomen). Tegen 1996 kon je een 3D grafische versneller kopen van 3dfx Interactive, zodat je de first-person shooter Quake op volle snelheid kon draaien.

Eveneens in 1996 begon Nvidia te concurreren op de 3D-acceleratormarkt met zwakke producten, maar leerde aldaar en in 1999 introduceerde het de succesvolle GeForce 256, de eerste grafische kaart die een GPU werd genoemd. Destijds was de belangrijkste reden om een ​​GPU te hebben, om te gamen. Pas later gebruikten mensen GPU's voor wiskunde, wetenschap en techniek.

De oorsprong van CUDA

In 2003 onthulde een team van onderzoekers onder leiding van Ian Buck Brook, het eerste algemeen aanvaarde programmeermodel om C uit te breiden met data-parallelle constructies. Buck kwam later bij Nvidia en leidde de lancering van CUDA in 2006, de eerste commerciële oplossing voor algemeen computergebruik op GPU's.

OpenCL versus CUDA

CUDA-concurrent OpenCL werd in 2009 gelanceerd door Apple en de Khronos Group in een poging om een ​​standaard te bieden voor heterogeen computergebruik die niet beperkt was tot Intel / AMD-CPU's met Nvidia GPU's. Hoewel OpenCL aantrekkelijk klinkt vanwege zijn algemeenheid, heeft het niet zo goed gepresteerd als CUDA op Nvidia GPU's, en veel deep learning-frameworks ondersteunen het niet of ondersteunen het alleen als een bijzaak zodra hun CUDA-ondersteuning is vrijgegeven.

CUDA-prestatieverbetering

CUDA heeft zijn bereik in de loop der jaren verbeterd en uitgebreid, min of meer in lockstep met verbeterde Nvidia GPU's. Vanaf CUDA versie 9.2 kunt u met behulp van meerdere P100 server GPU's tot 50x prestatieverbeteringen realiseren ten opzichte van CPU's. De V100 (niet weergegeven in deze afbeelding) is voor sommige belastingen nog eens 3x sneller. De vorige generatie server-GPU's, de K80, bood 5x tot 12x prestatieverbeteringen ten opzichte van CPU's.

Nvidia

De snelheidsboost van GPU's is op het nippertje gekomen voor high-performance computing. De single-threaded prestatieverbetering van CPU's in de loop van de tijd, waarvan de wet van Moore suggereerde dat deze elke 18 maanden zou verdubbelen, is vertraagd tot 10 procent per jaar omdat chipfabrikanten fysieke limieten tegenkwamen, waaronder groottelimieten voor de resolutie van chipmaskers en chipopbrengst tijdens het productieproces en hittelimieten op klokfrequenties tijdens runtime.

Nvidia

CUDA-toepassingsdomeinen

Nvidia

CUDA- en Nvidia-GPU's zijn gebruikt in veel gebieden die hoge floating-point computerprestaties vereisen, zoals geïllustreerd in de bovenstaande afbeelding. Een meer uitgebreide lijst bevat:

  1. Computationele financiën
  2. Klimaat-, weer- en oceaanmodellering
  3. Datawetenschap en analyse
  4. Diep leren en machine learning
  5. Defensie en inlichtingen
  6. Productie / AEC (architectuur, engineering en constructie): CAD en CAE (inclusief computationele vloeistofdynamica, computationele structurele mechanica, ontwerp en visualisatie en elektronische ontwerpautomatisering)
  7. Media en entertainment (inclusief animatie, modellering en rendering; kleurcorrectie en korrelbeheer; compositie; afwerking en effecten; bewerking; codering en digitale distributie; on-air graphics; on-set, review en stereo-tools; en weerafbeeldingen)
  8. Medische beeldvorming
  9. Olie en gas
  10. Onderzoek: hoger onderwijs en supercomputing (inclusief computationele chemie en biologie, numerieke analyse, natuurkunde en wetenschappelijke visualisatie)
  11. Veiligheid en beveiliging
  12. Tools en beheer

CUDA in diep leren

Deep learning heeft een te grote behoefte aan computersnelheid. Om bijvoorbeeld de modellen voor Google Translate in 2016 te trainen, hebben de teams van Google Brain en Google Translate honderden TensorFlow-runs van een week uitgevoerd met GPU's; daarvoor hadden ze 2.000 server-grade GPU's van Nvidia gekocht. Zonder GPU's zouden die trainingsruns maanden in plaats van een week hebben geduurd om samen te komen. Voor de productie van die TensorFlow-vertaalmodellen gebruikte Google een nieuwe aangepaste verwerkingschip, de TPU (tensor processing unit).

Naast TensorFlow vertrouwen veel andere DL-frameworks op CUDA voor hun GPU-ondersteuning, waaronder Caffe2, CNTK, Databricks, H2O.ai, Keras, MXNet, PyTorch, Theano en Torch. In de meeste gevallen gebruiken ze de cuDNN-bibliotheek voor de diepe neurale netwerkberekeningen. Die bibliotheek is zo belangrijk voor de training van de deep learning-frameworks dat alle frameworks die een bepaalde versie van cuDNN gebruiken in wezen dezelfde prestatienummers hebben voor gelijkwaardige use-cases. Wanneer CUDA en cuDNN van versie tot versie verbeteren, zien alle deep learning-frameworks die worden bijgewerkt naar de nieuwe versie de prestatiewinst. Waar de prestaties van framework tot framework verschillen, is hoe goed ze kunnen worden geschaald naar meerdere GPU's en meerdere knooppunten.

CUDA-programmering

Nvidia

CUDA Toolkit

De CUDA Toolkit bevat bibliotheken, hulpprogramma's voor foutopsporing en optimalisatie, een compiler, documentatie en een runtime-bibliotheek om uw applicaties te implementeren. Het heeft componenten die deep learning, lineaire algebra, signaalverwerking en parallelle algoritmen ondersteunen. Over het algemeen ondersteunen CUDA-bibliotheken alle families van Nvidia GPU's, maar presteren ze het beste op de nieuwste generatie, zoals de V100, die 3x sneller kan zijn dan de P100 voor workloads voor deep learning-trainingen. Het gebruik van een of meer bibliotheken is de gemakkelijkste manier om van GPU's te profiteren, zolang de algoritmen die u nodig hebt, zijn geïmplementeerd in de juiste bibliotheek.

Nvidia

CUDA deep learning-bibliotheken

Op het gebied van deep learning zijn er drie grote GPU-versnelde bibliotheken: cuDNN, dat ik eerder noemde als de GPU-component voor de meeste open source deep learning-frameworks; TensorRT, Nvidia's high-performance deep learning inferentie-optimalisatie en runtime; en DeepStream, een video-inferentiebibliotheek. TensorRT helpt u neurale netwerkmodellen te optimaliseren, te kalibreren voor lagere precisie met hoge nauwkeurigheid en de getrainde modellen te implementeren in clouds, datacenters, embedded systemen of automotive productplatforms.

Nvidia

CUDA lineaire algebra en wiskundige bibliotheken

Lineaire algebra ondersteunt tensorberekeningen en dus diep leren. BLAS (Basic Linear Algebra Subprograms), een verzameling matrixalgoritmen die in 1989 in Fortran zijn geïmplementeerd, wordt sindsdien gebruikt door wetenschappers en ingenieurs. cuBLAS is een GPU-versnelde versie van BLAS en de best presterende manier om matrixrekenen met GPU's uit te voeren. cuBLAS gaat ervan uit dat matrices dicht zijn; cuSPARSE verwerkt schaarse matrices.

Nvidia

CUDA-signaalverwerkingsbibliotheken

De snelle Fourier-transformatie (FFT) is een van de basisalgoritmen die worden gebruikt voor signaalverwerking; het verandert een signaal (zoals een audiogolfvorm) in een spectrum van frequenties. cuFFT is een GPU-versnelde FFT.

Codecs die standaarden gebruiken zoals H.264, coderen / comprimeren en decoderen / decomprimeren video voor verzending en weergave. De Nvidia Video Codec SDK versnelt dit proces met GPU's.

Nvidia

CUDA parallelle algoritmebibliotheken

De drie bibliotheken voor parallelle algoritmen hebben allemaal verschillende doelen. NCCL (Nvidia Collective Communications Library) is voor het schalen van apps over meerdere GPU's en knooppunten; nvGRAPH is voor parallelle grafiekanalyse; en Thrust is een C ++ sjabloonbibliotheek voor CUDA gebaseerd op de C ++ Standard Template Library. Thrust biedt een rijke verzameling gegevensparallelle primitieven zoals scannen, sorteren en verkleinen.

Nvidia

CUDA vs. CPU-prestaties

In sommige gevallen kunt u drop-in CUDA-functies gebruiken in plaats van de equivalente CPU-functies. De GEMM-matrixvermenigvuldigingsroutines van BLAS kunnen bijvoorbeeld worden vervangen door GPU-versies door simpelweg te linken naar de NVBLAS-bibliotheek:

Nvidia

Basisprincipes van CUDA programmeren

Als je CUDA-bibliotheekroutines niet kunt vinden om je programma's te versnellen, moet je CUDA-programmering op laag niveau proberen. Dat is nu veel gemakkelijker dan toen ik het eind jaren 2000 voor het eerst probeerde. Er is onder meer een eenvoudigere syntaxis en er zijn betere ontwikkeltools beschikbaar. Mijn enige klacht is dat op MacOS de nieuwste CUDA-compiler en de nieuwste C ++ -compiler (van Xcode) zelden synchroon lopen. Men moet oudere opdrachtregelprogramma's van Apple downloaden en ernaar overschakelen xcode-selectom de CUDA-code te compileren en te koppelen.

Overweeg bijvoorbeeld deze eenvoudige C / C ++ -routine om twee arrays toe te voegen:

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

{  

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

             y [ik] = x [ik] + y [ik];

}

U kunt er een kernel van maken die op de GPU wordt uitgevoerd door het __global__trefwoord aan de declaratie toe te voegen en de kernel aan te roepen met de syntaxis van de drievoudige haakjes:

voeg << >> (N, x, y) toe;

U moet ook uw malloc/ newen free/ deleteaanroepen naar cudaMallocManageden wijzigen cudaFreezodat u ruimte op de GPU toewijst. Ten slotte moet u wachten tot een GPU-berekening is voltooid voordat u de resultaten op de CPU gebruikt, waarmee u kunt bereiken cudaDeviceSynchronize.

De drievoudige beugel hierboven gebruikt één draadblok en één draad. Huidige Nvidia GPU's kunnen veel blokken en threads aan. Een Tesla P100 GPU op basis van de Pascal GPU-architectuur heeft bijvoorbeeld 56 Streaming Multiprocessors (SM's), die elk maximaal 2048 actieve threads kunnen ondersteunen.

De kernelcode zal zijn blok- en threadindex moeten kennen om zijn offset in de doorgegeven arrays te vinden. De parallelle kernel gebruikt vaak een grid-stride loop, zoals de volgende:

__globaal__

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

{

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

   int stride = blockDim.x * gridDim.x;

   voor (int i = index; i <n; i + = stride)

     y [ik] = x [ik] + y [ik];

}

Als je de voorbeelden in de CUDA Toolkit bekijkt, zul je zien dat er meer is om rekening mee te houden dan de basis die ik hierboven heb behandeld. Sommige CUDA-functieaanroepen moeten bijvoorbeeld in checkCudaErrors()oproepen worden verpakt . Ook zal in veel gevallen de snelste code bibliotheken gebruiken, zoals de cuBLAStoewijzing van host- en apparaatgeheugen en het heen en weer kopiëren van matrices.

Samenvattend kunt u uw apps op veel niveaus versnellen met GPU's. U kunt CUDA-code schrijven; je kunt CUDA-bibliotheken oproepen; en u kunt applicaties gebruiken die CUDA al ondersteunen.