Programavimas

Kas yra CUDA? Lygiagretus GPU programavimas

CUDA yra lygiagreti skaičiavimo platforma ir programavimo modelis, kurį „Nvidia“ sukūrė bendram skaičiavimui savo paties grafikos procesoriuose. CUDA leidžia kūrėjams paspartinti daug skaičiavimo reikalaujančias programas, pasinaudojant GPU galia lygiagrečiajai skaičiavimo daliai.

Nors buvo ir kitų GPU siūlomų API, tokių kaip „OpenCL“, ir yra konkurencingų kitų bendrovių, tokių kaip AMD, GPU, CUDA ir „Nvidia“ GPU derinys dominuoja keliose taikymo srityse, įskaitant gilų mokymąsi, ir yra pagrindas kai kuriems iš greičiausių kompiuterių pasaulyje.

Vaizdo plokštės neabejotinai yra tokios pat senos kaip asmeninis kompiuteris - tai yra, jei 1981 m. „IBM“ nespalvoto ekrano adapterį laikote vaizdo plokšte. Iki 1988 m. Galite gauti 16 bitų 2D VGA Wonder kortelę iš ATI (kompaniją galiausiai įsigijo AMD). Iki 1996 m. Galite įsigyti 3D grafikos greitintuvą iš „3dfx Interactive“, kad galėtumėte paleisti pirmo asmens šaudyklę „Quake“ visu greičiu.

Taip pat 1996 m. „Nvidia“ pradėjo bandyti konkuruoti 3D greitintuvų rinkoje su silpnais produktais, tačiau išmoko, kaip sekėsi, ir 1999 m. Pristatė sėkmingą „GeForce 256“ - pirmąją vaizdo plokštę, vadinamą GPU. Tuo metu pagrindinė GPU turėjimo priežastis buvo žaidimai. Tik vėliau žmonės naudojo grafikos procesorius matematikai, mokslams ir inžinerijai.

CUDA kilmė

2003 m. Mokslininkų komanda, vadovaujama Iano Bucko, pristatė Brooką - pirmąjį plačiai pritaikytą programavimo modelį, pratęsiantį C duomenis lygiagrečiomis konstrukcijomis. Vėliau Buckas prisijungė prie „Nvidia“ ir vadovavo CUDA paleidimui 2006 m. - pirmajam komerciniam sprendimui, skirtam bendros paskirties GPU skaičiavimui.

„OpenCL“ ir „CUDA“

„CUDA“ konkurentą „OpenCL“ „Apple“ ir „Khronos Group“ pradėjo 2009 m., Bandydami pateikti heterogeninio skaičiavimo standartą, kuris neapsiribotų „Intel / AMD“ procesoriais su „Nvidia“ GPU. Nors „OpenCL“ skamba patraukliai dėl savo bendrumo, „Nvidia“ GPU jis pasirodė ne taip gerai, kaip „CUDA“, o daugelis gilių mokymosi sistemų arba nepalaiko, arba palaiko tik kaip papildomą sumanymą, kai tik bus išleista jų CUDA parama.

CUDA našumas

Per kelerius metus CUDA patobulino ir išplėtė savo taikymo sritį, daugiau ar mažiau užrakinta su patobulintais „Nvidia“ GPU. Nuo CUDA 9.2 versijos, naudojant kelis P100 serverio GPU, galite realizuoti iki 50 kartų didesnį našumą, palyginti su procesoriais. V100 (neparodytas šiame paveikslėlyje) yra dar 3 kartus greitesnis kai kurioms apkrovoms. Ankstesnės kartos serverio GPU, K80, pasiūlė nuo 5 iki 12 kartų didesnį našumą, palyginti su procesoriais.

Nvidia

GPU spartos padidėjimas atėjo labai greitai, kai reikia didelio našumo skaičiavimo. Vieno sriegio procesoriaus našumas laikui bėgant, kurį Moore'o įstatymas pasiūlė padvigubinti kas 18 mėnesių, sulėtėjo iki 10 procentų per metus, nes lustų gamintojai susidūrė su fizinėmis ribomis, įskaitant lusto kaukės skiriamosios gebos dydžio apribojimus ir lusto derlingumą gamybos proceso metu. ir šilumos ribos laikrodžio dažniams vykdymo metu.

Nvidia

CUDA programų domenai

Nvidia

CUDA ir „Nvidia“ GPU buvo pritaikyti daugelyje sričių, kurioms reikalingi aukšti slankiojo kablelio skaičiavimo našumai, kaip vaizdžiai apibendrinta aukščiau esančiame paveikslėlyje. Išsamesnį sąrašą sudaro:

  1. Skaičiavimo finansai
  2. Klimato, orų ir vandenynų modeliavimas
  3. Duomenų mokslas ir analizė
  4. Gilus mokymasis ir mašininis mokymasis
  5. Gynyba ir žvalgyba
  6. Gamyba / AEC (architektūra, inžinerija ir statyba): CAD ir CAE (įskaitant skaičiavimo skysčių dinamiką, skaičiavimo struktūrinę mechaniką, dizainą ir vizualizaciją bei elektroninę dizaino automatiką)
  7. Žiniasklaida ir pramogos (įskaitant animaciją, modeliavimą ir perteikimą; spalvų korekciją ir grūdelių valdymą; komponavimą; apdailą ir efektus; redagavimą; kodavimą ir skaitmeninį platinimą; eterinę grafiką; filmavimo, peržiūros ir stereo įrankius; ir orų grafiką)
  8. Medicininis vaizdavimas
  9. Nafta ir dujos
  10. Tyrimai: Aukštasis mokslas ir superkompiuterija (įskaitant kompiuterinę chemiją ir biologiją, skaitinę analizę, fiziką ir mokslinę vizualizaciją)
  11. Saugumas ir apsauga
  12. Įrankiai ir valdymas

CUDA giliai mokantis

Gilus mokymasis turi didesnį skaičiavimo greičio poreikį. Pavyzdžiui, norėdami mokyti „Google“ vertėjo modelius 2016 m., „Google Brain“ ir „Google Translate“ komandos atliko šimtus vienos savaitės „TensorFlow“ bėgimų naudodamos GPU; jie tam tikslui iš „Nvidia“ buvo nusipirkę 2000 serverio lygio GPU. Jei nebūtų GPU, šioms treniruotėms suartėti būtų reikėję mėnesių, o ne savaitės. Šių „TensorFlow“ vertimo modelių gamybai diegti „Google“ naudojo naują pasirinktinį apdorojimo lustą - TPU (tensoriaus apdorojimo įrenginį).

Be „TensorFlow“, daugelis kitų DL sistemų remiasi CUDA savo GPU palaikymu, įskaitant „Caffe2“, „CNTK“, „Databricks“, „H2O.ai“, „Keras“, „MXNet“, „PyTorch“, „Theano“ ir „Torch“. Daugeliu atvejų jie naudoja cuDNN biblioteką giliųjų nervų tinklo skaičiavimams atlikti. Ta biblioteka yra tokia svarbi giliųjų mokymosi sistemų mokymui, kad visos sistemos, naudojančios tam tikrą cuDNN versiją, iš esmės turi vienodus eksploatacinius skaičius lygiaverčiais naudojimo atvejais. Kai CUDA ir „cuDNN“ tobulėja iš vienos versijos į kitą, visos gilaus mokymosi sistemos, kurios atnaujinamos į naują versiją, padidina našumą. Kuris našumas paprastai skiriasi, atsižvelgiant į tai, kaip jie keičiasi į kelis GPU ir kelis mazgus.

CUDA programavimas

Nvidia

CUDA priemonių rinkinys

CUDA įrankių rinkinyje yra bibliotekos, derinimo ir optimizavimo įrankiai, kompiliatorius, dokumentai ir vykdymo laiko biblioteka, skirta jūsų programoms diegti. Jame yra komponentai, palaikantys gilų mokymąsi, linijinę algebrą, signalo apdorojimą ir lygiagrečius algoritmus. Apskritai CUDA bibliotekos palaiko visas „Nvidia“ GPU šeimas, tačiau geriausiai veikia naujausios kartos, pvz., „V100“, kuris gali būti 3 kartus greitesnis nei „P100“, jei reikia gilaus mokymosi mokymo krūvio. Vienos ar kelių bibliotekų naudojimas yra lengviausias būdas pasinaudoti GPU, jei tik jums reikalingi algoritmai yra įdiegti atitinkamoje bibliotekoje.

Nvidia

CUDA gilaus mokymosi bibliotekos

Gilaus mokymosi srityje yra trys pagrindinės GPU pagreitintos bibliotekos: cuDNN, kurią anksčiau minėjau kaip GPU komponentą daugumai atvirojo kodo gilaus mokymosi sistemų; „TensorRT“, kuris yra didelio našumo „Nvidia“ giluminio mokymosi išvadų optimizavimo ir vykdymo laikas; ir „DeepStream“ - vaizdo išvadų biblioteka. „TensorRT“ padeda optimizuoti neuroninių tinklų modelius, labai tiksliai sukalibruoti, kad būtų mažesnis tikslumas, ir apmokytus modelius pritaikyti debesyse, duomenų centruose, įterptosiose sistemose ar automobilių produktų platformose.

Nvidia

CUDA linijinės algebros ir matematikos bibliotekos

Tiesinė algebra yra įtempių skaičiavimų ir todėl gilaus mokymosi pagrindas. BLAS (Basic Linear Algebra Subprograms) - matricų algoritmų rinkinys, įdiegtas Fortran 1989 m., Nuo to laiko naudojamas mokslininkų ir inžinierių. „cuBLAS“ yra GPU pagreitinta BLAS versija ir efektyviausias būdas atlikti matricos aritmetiką su GPU. cuBLAS daro prielaidą, kad matricos yra tankios; „cuSPARSE“ tvarko retas matricas.

Nvidia

CUDA signalo apdorojimo bibliotekos

Greita Furjė transformacija (FFT) yra vienas iš pagrindinių algoritmų, naudojamų signalų apdorojimui; jis signalą (pvz., garso bangos formą) paverčia dažnių spektru. cuFFT yra GPU pagreitinta FFT.

Kodekai, naudojant tokius standartus kaip H.264, koduoja / suspaudžia ir iššifruoja / išspausto vaizdo įrašą perdavimui ir rodymui. „Nvidia Video Codec SDK“ pagreitina šį procesą su GPU.

Nvidia

CUDA lygiagrečių algoritmų bibliotekos

Trys lygiagrečių algoritmų bibliotekos turi skirtingus tikslus. NCCL („Nvidia Collective Communications Library“) skirta programoms keisti keliuose GPU ir mazguose; nvGRAPH skirtas lygiagrečiai grafikų analizei; ir „Thrust“ yra CUDA C ++ šablonų biblioteka, pagrįsta C ++ standartinių šablonų biblioteka. Trauka suteikia daugybę lygiagrečių primityvių duomenų, tokių kaip nuskaitymas, rūšiavimas ir sumažinimas.

Nvidia

CUDA ir procesoriaus našumas

Kai kuriais atvejais vietoj lygiaverčių procesoriaus funkcijų galite naudoti „drop-in“ CUDA funkcijas. Pvz., BLAS GEMM matricos dauginimo įpročius galima pakeisti GPU versijomis, tiesiog susiejant su NVBLAS biblioteka:

Nvidia

CUDA programavimo pagrindai

Jei nerandate CUDA bibliotekos tvarkos, kad pagreitintumėte savo programas, turėsite išbandyti savo jėgas žemo lygio CUDA programavime. Tai dabar daug lengviau nei tada, kai pirmą kartą išbandžiau 2000-ųjų pabaigoje. Be kitų priežasčių, yra lengvesnė sintaksė ir yra geresnių kūrimo įrankių. Vienintelis mano klausimas yra tai, kad „MacOS“ naujausias CUDA kompiliatorius ir naujausias C ++ kompiliatorius (iš „Xcode“) retai kada sinchronizuojami. Reikia atsisiųsti senesnius komandinės eilutės įrankius iš „Apple“ ir pereiti prie jų naudojant „xcode-select“ kad gautumėte CUDA kodą sukompiliuoti ir susieti.

Pvz., Apsvarstykite šią paprastą C / C ++ procedūrą, kad pridėtumėte du masyvus:

negaliojantis pridėjimas (int n, float * x, float * y)

{  

už (int i = 0; i <n; i ++)

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

}

Galite jį paversti branduoliu, kuris veiks GPU, pridedant __global__ deklaracijos raktinį žodį ir iškvieskite branduolį naudodami trigubo skliaustelio sintaksę:

pridėti << >> (N, x, y);

Jūs taip pat turite pakeisti savo malloc/naujas ir Laisvas/Ištrinti skambučiai į cudaMallocTvarkoma ir cudaNėra kad paskirstytumėte vietą GPU. Galiausiai, prieš naudodamiesi procesoriaus rezultatais, kuriuos galite atlikti, turite palaukti, kol bus baigtas GPU skaičiavimas cudaDeviceSynchronize.

Aukščiau pateiktame trigubame laikiklyje naudojamas vienas sriegio blokas ir vienas sriegis. Dabartiniai „Nvidia“ GPU gali valdyti daugelį blokų ir gijų. Pavyzdžiui, „Tesla P100“ GPU, pagrįstame „Pascal GPU Architecture“, yra 56 srautiniai daugiaprocesoriai (SM), kurių kiekvienas gali palaikyti iki 2048 aktyvių gijų.

Branduolio kodas turės žinoti jo bloką ir gijos indeksą, kad surastų jo poslinkį į perduotus masyvus. Paraleliuotas branduolys dažnai naudoja a tinklelis-žingsnis kilpa, pavyzdžiui:

__global__

anuliuoti pridėjimą (int n, float * x, float * y)

{

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

int žingsnis = blockDim.x * gridDim.x;

for (int i = indeksas; i <n; i + = žingsnis)

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

}

Pažvelgę ​​į CUDA įrankių rinkinio pavyzdžius pamatysite, kad reikia apsvarstyti daugiau nei pagrindai, kuriuos apžvelgiau aukščiau. Pvz., Kai kuriuos CUDA funkcijos iškvietimus reikia įtraukti checkCudaErrors () skambučių. Be to, daugeliu atvejų greičiausiame kode bus naudojamos tokios bibliotekos kaip cuBLAS kartu su pagrindinės ir įrenginio atminties paskirstymu ir matricų kopijavimu pirmyn ir atgal.

Apibendrinant galima teigti, kad galite pagreitinti savo programas naudodami daugelio lygių GPU. Galite parašyti CUDA kodą; galite skambinti į CUDA bibliotekas; ir galite naudoti programas, kurios jau palaiko CUDA.