Skaičiavimai įjungti GPU

CUDA (Compute Unified Device Architecture) technologija – tai programinės ir techninės įrangos architektūra, leidžianti skaičiuoti naudojant NVIDIA GPU, palaikančius GPGPU (savavališko skaičiavimo vaizdo plokštėse) technologiją. CUDA architektūra pirmą kartą pasirodė rinkoje išleidus aštuntos kartos NVIDIA lustą - G80 ir yra visose tolesnėse grafikos lustų serijose, kurios naudojamos GeForce, ION, Quadro ir Tesla greitintuvų šeimose.

CUDA SDK leidžia programuotojams specialiu supaprastintu C programavimo kalbos dialektu įdiegti algoritmus, kurie gali būti paleisti NVIDIA GPU ir įtraukti specialias funkcijas į C programos tekstą. CUDA suteikia kūrėjui galimybę savo nuožiūra organizuoti prieigą prie grafikos greitintuvo instrukcijų rinkinio ir valdyti jo atmintį, organizuoti jame sudėtingą lygiagretųjį skaičiavimą.

Istorija

2003 m. „Intel“ ir „AMD“ varžėsi dėl daugiausia galingas procesorius. Bėgant metams dėl šių lenktynių laikrodžio dažnis gerokai išaugo, ypač išleidus Intel Pentium 4.

Padidinus laikrodžių dažnius (2001–2003 m. „Pentium 4“ laikrodžio dažnis padvigubėjo nuo 1,5 iki 3 GHz), vartotojai turėjo pasitenkinti dešimtosiomis gigahercų dalimis, kurias gamintojai pristatė į rinką (2003–2005 m. dažniai padidėjo nuo 3 iki 3,8 GHz).

Dideliam laikrodžio greičiui optimizuotos architektūros, tokios kaip Prescott, taip pat pradėjo patirti sunkumų, ir ne tik gamyboje. Lustų gamintojai susidūrė su iššūkiais įveikdami fizikos dėsnius. Kai kurie analitikai netgi prognozavo, kad Moore'o įstatymas nustos galioti. Bet taip neatsitiko. Pradinė įstatymo prasmė dažnai klaidingai pateikiama, tačiau ji nurodo tranzistorių skaičių silicio šerdies paviršiuje. Ilgam laikui procesoriaus tranzistorių skaičiaus padidėjimą lydėjo atitinkamas našumo padidėjimas – tai lėmė prasmės iškraipymą. Tačiau vėliau situacija tapo sudėtingesnė. CPU architektūros kūrėjai priartėjo prie stiprinimo mažinimo dėsnio: tranzistorių, kuriuos reikėjo pridėti norint padidinti našumą, vis daugėjo, todėl atsidūrė aklavietė.

Priežastis, kodėl GPU gamintojai nesusidūrė su šia problema, yra labai paprasta: centriniai procesoriai sukurti taip, kad gautų geriausią našumą komandų sraute, kuris apdoroja skirtingus duomenis (tiek sveikuosius, tiek slankiojo kablelio skaičius), atlieka atsitiktinę prieigą prie atminties ir pan. Iki šiol kūrėjai stengėsi užtikrinti didesnį instrukcijų lygiagretumą – tai yra lygiagrečiai vykdyti kuo daugiau instrukcijų. Taigi, pavyzdžiui, su Pentium atsirado superskaliarinis vykdymas, kai tam tikromis sąlygomis buvo galima vykdyti dvi komandas per laikrodį. Pentium Pro gavo netvarkingą instrukcijų vykdymą, o tai leido optimizuoti skaičiavimo vienetų našumą. Problema ta, kad lygiagretus nuoseklaus komandų srauto vykdymas turi akivaizdžių apribojimų, todėl aklas skaičiavimo vienetų skaičiaus didinimas neduoda naudos, nes dažniausiai jie vis tiek bus nenaudojami.

GPU veikimas yra gana paprastas. Jį sudaro daugiakampių grupės paėmimas iš vienos pusės ir pikselių grupės generavimas kitoje. Daugiakampiai ir pikseliai yra nepriklausomi vienas nuo kito, todėl juos galima apdoroti lygiagrečiai. Taigi GPU galima didelę kristalo dalį skirti skaičiavimo vienetams, kurie, skirtingai nei CPU, bus iš tikrųjų naudojami.

GPU nuo procesoriaus skiriasi ne tik tuo. Atminties prieiga GPU yra labai susieta – jei nuskaitomas tekselis, tada po kelių ciklų bus nuskaitomas gretimas tekselis; kai įrašomas pikselis, po kelių ciklų bus parašytas greta esantis pikselis. Išmaniai tvarkydami atmintį galite pasiekti, kad našumas būtų artimas teoriniam pralaidumui. Tai reiškia, kad GPU, skirtingai nei CPU, nereikalauja didžiulės talpyklos, nes jo vaidmuo yra pagreitinti tekstūravimo operacijas. Tereikia kelių kilobaitų, kuriuose yra keli tekseliai, naudojami dvilinijiniuose ir trilinijiniuose filtruose.

Pirmieji GPU skaičiavimai

Pirmieji tokios programos bandymai apsiribojo kai kurių aparatinės įrangos funkcijų, tokių kaip rastravimas ir Z-buferis, naudojimu. Tačiau dabartiniame amžiuje, atsiradus šešėliams, jie pradėjo spartinti matricų skaičiavimą. 2003 m. SIGGRAPH buvo skirtas atskiras skyrius, skirtas GPU skaičiavimui, ir jis vadinosi GPGPU (General-Purpose computation on GPU) – universalus GPU skaičiavimas).

Geriausiai žinomas BrookGPU yra Brook srauto programavimo kalbos kompiliatorius, skirtas atlikti negrafinius GPU skaičiavimus. Prieš pasirodant, kūrėjai, naudojantys vaizdo lustų galimybes skaičiavimams, pasirinko vieną iš dviejų įprastų API: Direct3D arba OpenGL. Tai rimtai apribojo GPU naudojimą, nes 3D grafikoje naudojami šešėliai ir tekstūros, apie kurias lygiagrečiai programuotojai neprivalo žinoti, jie naudoja gijas ir branduolius. Brook galėjo padėti palengvinti jų užduotį. Šie C kalbos transliacijos plėtiniai, sukurti Stanfordo universitete, paslėpė 3D API nuo programuotojų ir pristatė vaizdo lustą kaip lygiagretųjį koprocesorių. Kompiliatorius išanalizavo .br failą su C++ kodu ir plėtiniais, sukurdamas kodą, susietą su DirectX, OpenGL arba x86 biblioteka.

„Brook“ pasirodymas sukėlė NVIDIA ir ATI susidomėjimą ir dar labiau atvėrė visiškai naują jos sektorių – lygiagrečius kompiuterius, pagrįstus vaizdo lustais.

Be to, kai kurie Brook projekto tyrėjai persikėlė į NVIDIA kūrėjų komandą, kad pristatytų aparatinės ir programinės įrangos lygiagrečiojo skaičiavimo strategiją, atveriant naują rinkos dalį. O pagrindinis šios NVIDIA iniciatyvos privalumas buvo tas, kad kūrėjai puikiai išmano visas savo GPU galimybes iki smulkmenų ir nereikia naudoti grafinės API, o dirbti su aparatūra galima tiesiogiai naudojant tvarkyklę. Šios komandos pastangų rezultatas – NVIDIA CUDA.

Lygiagrečių skaičiavimų GPU taikymo sritys

Kai skaičiavimas perkeliamas į GPU, daugelyje užduočių pagreitis pasiekiamas 5-30 kartų, palyginti su greitais bendrosios paskirties procesoriais. Didžiausi skaičiai (100 kartų ir net daugiau!) pasiekiami naudojant kodą, kuris nėra labai tinkamas skaičiavimams naudojant SSE blokus, tačiau yra gana patogus GPU.

Tai tik keli sintetinio kodo pagreitinimo GPU ir SSE vektorizuoto procesoriaus kodo pavyzdžiai (pagal NVIDIA):

Fluorescencinė mikroskopija: 12x.

Molekulinė dinamika (nesurištos jėgos skaičiuok.): 8-16x;

Elektrostatika (tiesioginė ir daugiapakopė Kulono suma): 40-120x ir 7x.

Lentelė, kurią NVIDIA rodo visuose pristatymuose, kurioje rodomas GPU greitis, palyginti su procesoriais.

Pagrindinių programų, kuriose naudojamas GPU skaičiavimas, sąrašas: vaizdo ir signalų analizė ir apdorojimas, fizinis modeliavimas, skaičiavimo matematika, skaičiavimo biologija, finansiniai skaičiavimai, duomenų bazės, dujų ir skysčių dinamika, kriptografija, adaptyvioji spindulinė terapija, astronomija, garso apdorojimas, bioinformatika, biologinis modeliavimas, kompiuterinis matymas, duomenų gavyba, skaitmeninis kinas ir televizija, elektromagnetinis modeliavimas, geografinės informacijos sistemos, karinės programos, kasybos planavimas, molekulinė dinamika, magnetinio rezonanso tomografija (MRT), neuroniniai tinklai, okeanografiniai tyrimai, dalelių fizika, baltymų lankstymo modeliavimas, kvantinė chemija, spindulių sekimas, vaizdavimas, radaras, rezervuaro modeliavimas, dirbtinis intelektas, palydovinių duomenų analizė, seisminis tyrinėjimas, chirurgija, ultragarsas, vaizdo konferencijos.

CUDA pranašumai ir apribojimai

Programuotojo požiūriu, grafinis konvejeris yra apdorojimo etapų rinkinys. Geometrijos blokas generuoja trikampius, o rastrizacijos blokas – monitoriuje rodomus pikselius. Tradicinis GPGPU programavimo modelis yra toks:

Norint perkelti skaičiavimus į GPU pagal tokį modelį, reikia specialaus požiūrio. Netgi pridedant du vektorius kiekvienam elementui reikės piešti figūrą į ekraną arba į ne ekrano buferį. Figūra rastrizuota, kiekvieno pikselio spalva apskaičiuojama pagal duotą programą (pixel shader). Programa nuskaito įvesties duomenis iš kiekvieno pikselio tekstūrų, juos sudeda ir įrašo į išvesties buferį. Ir visos šios daugybės operacijų reikalingos tam, kas parašyta vienu operatoriumi įprastine programavimo kalba!

Todėl GPGPU naudojimas bendrosios paskirties kompiuteriams yra ribotas, nes kūrėjams per daug sudėtinga mokytis. Ir yra pakankamai kitų apribojimų, nes pixel shader yra tik galutinės pikselio spalvos priklausomybės nuo jo koordinačių formulė, o pixel shader kalba yra šių formulių rašymo kalba su C tipo sintaksė. Ankstyvieji GPGPU metodai yra gudrus triukas, leidžiantis panaudoti GPU galią, tačiau be jokio patogumo. Ten esantys duomenys atvaizduojami vaizdais (tekstūros), o algoritmas – rastrizacijos procesu. Reikėtų pažymėti ir labai specifinį atminties ir vykdymo modelį.

NVIDIA aparatinės ir programinės įrangos architektūra, skirta skaičiavimui naudojant NVIDIA GPU, skiriasi nuo ankstesnių GPGPU modelių tuo, kad leidžia GPU programas rašyti realiu C formatu su standartine sintaksė, rodyklėmis ir būtinybe turėti minimalų plėtinį, kad būtų galima pasiekti vaizdo lustų skaičiavimo išteklius. CUDA nepriklauso nuo grafinių API ir turi kai kurias funkcijas, specialiai sukurtas bendrosios paskirties kompiuteriams.

CUDA pranašumai prieš tradicinį požiūrį į GPGPU skaičiavimą

CUDA suteikia prieigą prie 16 KB bendros atminties vienam kelių procesorių, kurią galima naudoti talpyklai sutvarkyti didesniu pralaidumu nei tekstūros gavimas;

Efektyvesnis duomenų perdavimas tarp sistemos ir vaizdo atminties;

Nereikia grafikos API su pertekliumi ir pridėtinėmis išlaidomis;

Linijinis atminties adresavimas, rinkimas ir išsklaidymas, galimybė rašyti savavališkais adresais;

Aparatinės įrangos palaikymas sveikųjų ir bitų operacijoms.

Pagrindiniai CUDA apribojimai:

Vykdomųjų funkcijų rekursijos palaikymo trūkumas;

Mažiausias bloko plotis yra 32 sriegiai;

Uždara CUDA architektūra, priklausanti NVIDIA.

Ankstesnių GPGPU metodų programavimo trūkumai yra tai, kad šie metodai nenaudoja viršūnių šešėlių vykdymo vienetų ankstesnėse nesuvienodintose architektūrose, duomenys saugomi tekstūrose ir išvedami į ne ekrano buferį, o kelių žingsnių algoritmai naudoja pikselių šešėliavimo vienetus. GPGPU apribojimai apima: nepakankamai efektyvų aparatinės įrangos galimybių naudojimą, atminties pralaidumo apribojimus, jokios sklaidos operacijos (tik rinkimas), privalomą grafikos API naudojimą.

Pagrindiniai CUDA pranašumai, palyginti su ankstesniais GPGPU metodais, kyla iš to, kad ši architektūra skirta efektyvus naudojimas negrafinį skaičiavimą GPU ir naudoja C programavimo kalbą, nereikalaujant perkelti algoritmų į formą, patogią grafinio konvejerio koncepcijai. CUDA siūlo naujas būdas GPU kompiuterija, kuri nenaudoja grafikos API ir siūlo atsitiktinę prieigą prie atminties (išsklaidyti arba surinkti). Tokia architektūra neturi GPGPU trūkumų ir naudoja visus vykdymo vienetus, taip pat išplečia galimybes per sveikųjų skaičių matematiką ir bitų poslinkio operacijas.

CUDA atveria kai kurias aparatinės įrangos funkcijas, kurių nėra grafikos API, pvz., bendrinamą atmintį. Tai nedidelis atminties kiekis (16 kilobaitų vienam procesoriui), prie kurio gali patekti gijų blokai. Tai leidžia talpykloje išsaugoti dažniausiai pasiekiamus duomenis ir pateikti daugiau didelis greitis, palyginti su tekstūros gavimu šiai užduočiai atlikti. Tai savo ruožtu sumažina lygiagrečių algoritmų pralaidumo jautrumą daugelyje programų. Pavyzdžiui, tai naudinga tiesinei algebrai, greitajai Furjė transformacijai ir vaizdo apdorojimo filtrams.

Patogiau naudojant CUDA ir prieigą prie atminties. Programos kodas grafikos API išveda duomenis kaip 32 vieno tikslumo slankiojo kablelio vertes (RGBA reikšmės vienu metu aštuoniuose atvaizdavimo taikiniuose) iš anksto nustatytose srityse, o CUDA palaiko sklaidos įrašymą - neribotą įrašų skaičių bet kuriuo adresu. . Tokie pranašumai leidžia vykdyti kai kuriuos GPU algoritmus, kurių negalima efektyviai įgyvendinti naudojant GPGPU metodus, pagrįstus grafine API.

Taip pat grafinės API būtinai saugo duomenis tekstūrose, todėl iš anksto reikia supakuoti didelius masyvus į tekstūras, o tai apsunkina algoritmą ir verčia naudoti specialų adresavimą. O CUDA leidžia skaityti duomenis bet kuriuo adresu. Kitas CUDA pranašumas yra optimizuotas ryšys tarp procesoriaus ir GPU. O kūrėjams, norintiems pasiekti žemą lygį (pavyzdžiui, rašant kitą programavimo kalbą), CUDA siūlo žemo lygio asamblėjos kalbos programavimo galimybę.

CUDA trūkumai

Vienas iš nedaugelio CUDA trūkumų yra prastas nešiojamumas. Ši architektūra veikia tik šios kompanijos vaizdo lustuose, ir ne visose, o pradedant nuo GeForce 8 ir 9 serijų bei atitinkamų Quadro, ION ir Tesla. NVIDIA pateikia 90 milijonų su CUDA suderinamų vaizdo lustų skaičių.

CUDA alternatyvos

Rašymo rėmai kompiuterines programas susijęs su lygiagrečiu skaičiavimu įvairiuose grafiniuose ir centriniuose procesoriuose. OpenCL sistema apima C99 standartu pagrįstą programavimo kalbą ir taikomųjų programų programavimo sąsają (API). OpenCL suteikia instrukcijų ir duomenų lygiagretumą ir yra GPGPU technikos įgyvendinimas. „OpenCL“ yra visiškai atviras standartas ir jo naudojimas nekainuoja jokių licencijų mokesčių.

OpenCL tikslas yra papildyti OpenGL ir OpenAL, kurie yra atviri pramoniniai 3D kompiuterinės grafikos ir garso standartai, pasinaudojant GPU galia. „OpenCL“ kuria ir prižiūri „Khronos Group“ – pelno nesiekiantis konsorciumas, kurį sudaro daugybė didelių kompanijų, įskaitant „Apple“, AMD, „Intel“, „nVidia“, „Sun Microsystems“, „Sony Computer Entertainment“ ir kt.

CAL / IL (apskaičiavimo abstrakcijos sluoksnis / tarpinė kalba)

ATI Stream Technology yra aparatinės įrangos ir programinės įrangos technologijas, kurie leidžia naudoti AMD GPU kartu su centriniu procesoriumi, kad pagreitintumėte daugelį programų (ne tik grafinių).

„ATI Stream“ taikymo sritys yra programos, kurios reikalauja daug kompiuterinių išteklių, pvz finansinę analizę arba seisminis duomenų apdorojimas. Srauto procesoriaus naudojimas leido padidinti kai kurių finansinių skaičiavimų greitį 55 kartus, palyginti su tos pačios problemos sprendimu naudojant tik CPU.

NVIDIA nelaiko ATI Stream technologijos labai stipriu konkurentu. CUDA ir Stream yra dvi skirtingos technologijos, kurios yra skirtinguose vystymosi lygiuose. ATI produktų programavimas yra daug sunkesnis – jų kalba labiau primena asemblerį. Kita vertus, CUDA C yra daug aukštesnio lygio kalba. Rašyti ant jo patogiau ir lengviau. Didelėms plėtros įmonėms tai labai svarbu. Jei kalbėtume apie našumą, pamatytume, kad jo didžiausia vertė ATI gaminiuose yra didesnė nei NVIDIA sprendimuose. Bet vėlgi, viskas priklauso nuo to, kaip gauti šią galią.

„DirectX11“ („DirectCompute“)

Programų programavimo sąsaja, kuri yra „DirectX“ dalis – „Microsoft“ API rinkinys, skirtas veikti su IBM PC suderinamuose kompiuteriuose, kuriuose veikia Operacinės sistemos Microsoft Windows šeima. „DirectCompute“ skirta atlikti bendrosios paskirties GPU skaičiavimus, nes tai yra GPGPU koncepcijos įgyvendinimas. „DirectCompute“ iš pradžių buvo paskelbta kaip „DirectX 11“ dalis, tačiau vėliau buvo prieinama ir „DirectX 10“ bei „DirectX 10.1“.

NVDIA CUDA Rusijos mokslinėje aplinkoje.

2009 m. gruodžio mėn. programavimo modelis CUDA dėstoma 269 universitetuose visame pasaulyje. Rusijoje mokymo kursai apie CUDA vyksta Maskvos, Sankt Peterburgo, Kazanės, Novosibirsko ir Permės valstybiniuose universitetuose, Tarptautiniame visuomenės ir žmogaus gamtos universitete „Dubna“, Jungtiniame branduolinių tyrimų institute, Maskvos elektronikos institute. Technologijos, Ivanovo valstybinis energetikos universitetas, BSTU. V. G. Shukhova, MSTU im. Baumanas, RKhTU im. Mendelejevas, Rusijos tyrimų centras „Kurchatovo institutas“, Rusijos mokslų akademijos tarpregioninis superkompiuterių centras, Taganrogo technologijos institutas (TTI SFedU).

AMD/ATI Radeon architektūros ypatybės

Tai panašu į naujų biologinių rūšių gimimą, kai gyvos būtybės vystosi, kad pagerintų savo prisitaikymą prie aplinkos, vystantis buveinėms. Panašiai, GPU, pradedant pagreitintu trikampių rastravimu ir tekstūravimu, sukūrė papildomus gebėjimus vykdyti šešėlių programas, skirtas spalvinti tuos pačius trikampius. Ir pasirodė, kad šie gebėjimai yra paklausūs negrafiniame skaičiavime, kur kai kuriais atvejais jie suteikia didelį našumo padidėjimą, palyginti su tradiciniais sprendimais.

Analogijas brėžiame toliau – po ilgos evoliucijos sausumoje žinduoliai prasiskverbė į jūrą, kur išstūmė eilinius jūrų gyventojus. Varžybinėje kovoje žinduoliai naudojo ir naujus pažangius gebėjimus, atsiradusius žemės paviršiuje, ir specialiai įgytus prisitaikymui prie gyvenimo vandenyje. Lygiai taip pat GPU, remdamiesi 3D grafikos architektūros pranašumais, vis dažniau įgyja specialių funkcijų, naudingų ne grafinėms užduotims.

Taigi, kas leidžia GPU reikalauti savo sektoriaus bendrosios paskirties programų srityje? GPU mikroarchitektūra labai skiriasi nuo įprastų procesorių ir nuo pat pradžių turi tam tikrų privalumų. Grafikos užduotys apima nepriklausomą lygiagretų duomenų apdorojimą, o GPU iš prigimties yra kelių gijų. Tačiau šis paralelizmas jam tik džiaugsmas. Mikroarchitektūra sukurta siekiant išnaudoti daugybę gijų, kurias reikia vykdyti.

GPU susideda iš kelių dešimčių (30 Nvidia GT200, 20 Evergreen, 16 Fermi) procesoriaus branduolių, kurie Nvidia terminologijoje vadinami Streaming Multiprocessor, o ATI terminologija - SIMD Engine. Šiame straipsnyje mes juos vadinsime mini procesoriais, nes jie vykdo kelis šimtus programos gijų ir gali padaryti beveik viską, ką gali įprastas procesorius, bet vis tiek ne viską.

Rinkodaros pavadinimai klaidina – jie, siekiant didesnio svarbos, nurodo funkcinių modulių, galinčių atimti ir padauginti, skaičių: pavyzdžiui, 320 vektorinių „branduolių“ (branduolių). Šie branduoliai labiau primena grūdus. Geriau galvoti apie GPU kaip apie kelių branduolių procesorių, turintį daug branduolių, vienu metu vykdančių daug gijų.

Kiekvienas miniprocesorius turi vietinę atmintį, 16 KB GT200, 32 KB Evergreen ir 64 KB Fermi (iš esmės programuojama L1 talpykla). Jis turi panašų prieigos prie įprasto procesoriaus L1 talpyklos laiką ir atlieka panašias funkcijas, kuo greičiau tiekdamas duomenis į funkcinius modulius. „Fermi“ architektūroje vietinės atminties dalis gali būti sukonfigūruota kaip įprasta talpykla. GPU vietinė atmintis naudojama norint greitai keistis duomenimis tarp vykdomųjų gijų. Viena iš įprastų GPU programos schemų yra tokia: pirma, duomenys iš GPU pasaulinės atminties įkeliami į vietinę atmintį. Tai tik įprasta vaizdo atmintis (pvz sistemos atmintis) atskirai nuo "savo" procesoriaus - vaizdo atveju jis yra lituojamas keliomis mikroschemomis ant vaizdo plokštės tekstolito. Toliau keli šimtai gijų dirba su šiais duomenimis vietinėje atmintyje ir įrašo rezultatą į pasaulinę atmintį, o po to jis perkeliamas į centrinį procesorių. Programuotojas yra atsakingas už duomenų įkėlimo ir iškrovimo iš vietinės atminties instrukcijas. Iš esmės tai yra [konkrečios užduoties] duomenų skaidymas lygiagrečiam apdorojimui. GPU taip pat palaiko atomines rašymo/skaitymo instrukcijas į atmintį, tačiau jos yra neefektyvios ir dažniausiai reikalingos paskutiniame etape, norint „suklijuoti“ visų mini procesorių skaičiavimų rezultatus.

Vietinė atmintis yra bendra visoms miniprocesoriuje veikiančioms gijomis, todėl, pavyzdžiui, Nvidia terminologijoje ji netgi vadinama bendra, o terminas vietinė atmintis reiškia visiškai priešingą, būtent: tam tikrą asmeninę atskiros gijos sritį pasaulinėje sistemoje. atmintis, matoma ir pasiekiama tik jai. Tačiau be vietinės atminties, mini procesorius turi dar vieną atminties sritį, visose architektūrose, maždaug keturis kartus didesnės apimties. Jis yra padalintas po lygiai tarp visų vykdomųjų gijų; tai registrai, skirti kintamiesiems ir tarpiniams skaičiavimo rezultatams saugoti. Kiekviena gija turi kelias dešimtis registrų. Tikslus skaičius priklauso nuo to, kiek gijų veikia miniprocesorius. Šis skaičius yra labai svarbus, nes pasaulinės atminties delsa yra labai didelė, šimtai ciklų, o jei nėra talpyklos, nėra kur saugoti tarpinių skaičiavimų rezultatų.

Ir dar viena svarbi GPU savybė: „minkšta“ vektorizacija. Kiekvienas miniprocesorius turi daug skaičiavimo modulių (8 GT200, 16 Radeon ir 32 Fermi), tačiau jie gali vykdyti tik tą pačią komandą su tuo pačiu programos adresu. Operandai šiuo atveju gali būti skirtingi, skirtingos gijos turi savo. Pavyzdžiui, instrukcija pridėti dviejų registrų turinį: jį vienu metu vykdo visi skaičiavimo įrenginiai, tačiau paimami skirtingi registrai. Daroma prielaida, kad visos GPU programos gijos, atliekančios lygiagretų duomenų apdorojimą, paprastai juda lygiagrečia eiga per programos kodą. Taigi visi skaičiavimo moduliai įkeliami tolygiai. Ir jei gijos dėl šakų programoje išsiskyrė savo kodo vykdymo kelyje, tada įvyksta vadinamasis serializavimas. Tada naudojami ne visi skaičiavimo moduliai, nes gijos pateikia skirtingas vykdymo instrukcijas, o skaičiavimo modulių blokas gali vykdyti, kaip jau minėjome, tik komandą su vienu adresu. Ir, žinoma, našumas tuo pačiu metu krenta maksimaliai.

Privalumas tas, kad vektorizavimas yra visiškai automatinis, tai nėra programavimas naudojant SSE, MMX ir pan. O pats GPU tvarko neatitikimus. Teoriškai galima rašyti programas GPU negalvojant apie vykdomų modulių vektorinį pobūdį, tačiau tokios programos greitis nebus labai didelis. Minusas yra didelis vektoriaus plotis. Tai daugiau nei nominalus funkcinių modulių skaičius ir yra 32 Nvidia GPU ir 64 Radeon. Siūlai apdorojami atitinkamo dydžio blokais. „Nvidia“ šį gijų bloką vadina terminu warp, AMD – bangų frontas, o tai yra tas pats. Taigi 16-oje skaičiavimo įrenginių 64 gijų ilgio „bangos frontas“ apdorojamas keturiais ciklais (darant įprastą instrukcijos ilgį). Autorius šiuo atveju teikia pirmenybę terminui metmenys, nes siejamas su jūriniu terminu metmenys, reiškiantis iš susuktų virvių surištą virvę. Taigi siūlai „susisuka“ ir sudaro vientisą pluoštą. Tačiau „bangų frontą“ galima sieti ir su jūra: nurodymai į pavaras atkeliauja taip pat, kaip bangos viena po kitos rieda į krantą.

Jei visos gijos vienodai progresavo vykdant programą (jos yra toje pačioje vietoje) ir taip vykdo tą pačią komandą, tai viskas gerai, bet jei ne, tai sulėtėja. Šiuo atveju gijos iš to paties metmenų ar bangų fronto yra skirtingose ​​programos vietose, jos suskirstytos į gijų grupes, turinčias vienodą komandos numerio (kitaip tariant, komandos rodyklės) reikšmę. Ir kaip anksčiau, vienu metu vykdomos tik vienos grupės gijos – visos vykdo tą pačią komandą, tik su skirtingais operandais. Dėl to metmenys vykdomi tiek kartų lėčiau, kiek grupių jis suskirstytas, o gijų skaičius grupėje neturi reikšmės. Net jei grupę sudaro tik viena gija, ji vis tiek užtruks tiek pat, kiek ir visas metimas. Aparatinėje įrangoje tai įgyvendinama užmaskuojant tam tikras gijas, tai yra, instrukcijos yra formaliai vykdomos, tačiau jų vykdymo rezultatai niekur nefiksuojami ir nenaudojami ateityje.

Nors kiekvienas miniprocesorius (Streaming MultiProcessor arba SIMD Engine) bet kuriuo metu vykdo komandas, priklausančias tik vienam deformacijai (krūvei gijų), vykdomajame telkinyje jis turi kelias dešimtis aktyvių deformacijų. Įvykdęs vieno metmens instrukcijas, miniprocesorius savo ruožtu vykdo ne kitą šio metmenų gijų komandą, o kažkieno kito metmenų instrukcijas. Tas metmenys gali būti visiškai kitoje programos vietoje, tai neturės įtakos greičiui, nes tik deformacijoje visų gijų instrukcijos turi būti vienodos vykdant visu greičiu.

Šiuo atveju kiekvienas iš 20 SIMD variklių turi keturis aktyvius bangų frontus, kurių kiekvienas turi 64 gijas. Kiekvienas siūlas pažymėtas trumpa linija. Iš viso: 64×4×20=5120 gijų

Taigi, atsižvelgiant į tai, kad kiekvieną metmenų ar bangų frontą sudaro 32–64 gijos, mini procesorius turi kelis šimtus aktyvių gijų, kurios vykdomos beveik vienu metu. Žemiau pamatysime, kokią architektūrinę naudą žada toks didelis lygiagrečių gijų skaičius, bet pirmiausia apsvarstysime, kokius apribojimus turi GPU sudarantys mini procesoriai.

Svarbiausia, kad GPU neturi kamino, kuriame būtų galima saugoti funkcijų parametrus ir vietinius kintamuosius. Dėl daugybės gijų, skirtų kaminui, lustoje tiesiog nėra vietos. Iš tiesų, kadangi GPU vienu metu vykdo apie 10 000 gijų, kurių vienos gijos krūvos dydis yra 100 KB, bendra suma bus 1 GB, o tai yra lygi standartiniam visos vaizdo atminties kiekiui. Be to, pačiame GPU branduolyje jokiu būdu negalima įdėti kokio nors reikšmingo dydžio krūvos. Pavyzdžiui, jei vienai gijai įdėsite 1000 baitų krūvos, tada tik vienam mini procesoriui reikės 1 MB atminties, o tai beveik penkis kartus viršija bendrą mini procesoriaus vietinės atminties kiekį ir registrams saugoti skirtą atmintį.

Todėl GPU programoje nėra rekursijos ir tikrai negalite apsisukti su funkcijų iškvietimais. Visos funkcijos yra tiesiogiai pakeičiamos į kodą, kai programa sukompiliuojama. Tai apriboja GPU apimtį iki skaičiavimo užduočių. Kartais galima naudoti ribotą kamino emuliaciją, naudojant visuotinę atmintį rekursijos algoritmams su žinomu mažu iteracijos gyliu, tačiau tai nėra įprasta GPU programa. Norėdami tai padaryti, būtina specialiai sukurti algoritmą, ištirti jo įgyvendinimo galimybę be sėkmingo pagreičio garantijos, palyginti su CPU.

„Fermi“ pirmą kartą pristatė galimybę naudoti virtualias funkcijas, tačiau vėlgi, jų naudojimą riboja didelės, greitos kiekvienos gijos talpyklos trūkumas. 1536 gijos sudaro 48 KB arba 16 KB L1, tai yra, virtualias funkcijas programoje galima naudoti palyginti retai, kitaip dėklas taip pat naudos lėtą visuotinę atmintį, o tai sulėtins vykdymą ir, greičiausiai, neduos naudos, palyginti į CPU versiją.

Taigi GPU pateikiamas kaip skaičiavimo koprocesorius, į kurį įkeliami duomenys, jie apdorojami kažkokiu algoritmu ir gaunamas rezultatas.

Architektūros privalumai

Tačiau mano, kad GPU yra labai greitas. Ir tai jam padeda jo aukštas daugiasriegis siūlas. Didelis aktyvių gijų skaičius leidžia iš dalies paslėpti didelį atskirai esančios pasaulinės vaizdo atminties delsą, kuri yra apie 500 ciklų. Tai ypač gerai išlygina didelio tankio kodą. aritmetines operacijas. Taigi, tranzistorių brangios L1-L2-L3 talpyklos hierarchijos nereikia. Vietoj to, daugelis skaičiavimo modulių gali būti dedami į lustą, užtikrinantį puikų aritmetinį našumą. Tuo tarpu vienos gijos ar metmenų instrukcijos vykdomos, kiti šimtai gijų ramiai laukia savo duomenų.

„Fermi“ pristatė antrojo lygio apie 1 MB talpyklą, tačiau jos negalima lyginti su šiuolaikinių procesorių talpyklomis, ji labiau skirta komunikacijai tarp branduolių ir įvairioms programinės įrangos gudrybėms. Jei jo dydis bus padalintas į visas dešimtis tūkstančių gijų, kiekvieno jų kiekis bus labai nereikšmingas.

Tačiau, be visuotinės atminties delsos, skaičiavimo įrenginyje yra daug daugiau delsų, kurias reikia paslėpti. Tai yra duomenų perdavimo mikroschemos viduje iš skaičiavimo įrenginių į pirmojo lygio talpyklą, ty vietinę GPU atmintį, ir į registrus, taip pat instrukcijų talpyklą delsa. Registro failas, kaip ir vietinė atmintis, yra atskirai nuo funkcinių modulių, o prieigos prie jų greitis yra apie keliolika ciklų. Ir vėl daug gijų, aktyvių metmenų, gali veiksmingai paslėpti šį delsą. Be to, bendras prieigos prie viso GPU vietinės atminties pralaidumas (pralaidumas), atsižvelgiant į jį sudarančių mini procesorių skaičių, yra daug didesnis nei šiuolaikinių procesorių prieigos prie pirmojo lygio talpyklos pralaidumas. GPU gali apdoroti žymiai daugiau duomenų per laiko vienetą.

Iš karto galime pasakyti, kad jei GPU nebus aprūpinta daugybe lygiagrečių gijų, jis turės beveik nulinį našumą, nes dirbs tokiu pačiu tempu, tarsi būtų visiškai įkeltas, ir atliks daug mažiau darbo. Pavyzdžiui, tegul lieka tik viena gija, o ne 10 000: našumas sumažės maždaug tūkstantį kartų, nes ne tik nebus įkeliami visi blokai, bet ir visos delsos.

Latencijos slėpimo problema aktuali ir šiuolaikiniams aukšto dažnio procesoriams, jai pašalinti naudojami sudėtingi metodai – gilus konvejerinis keitimas, netvarkingas instrukcijų vykdymas (netvarkingas). Tam reikalingi sudėtingi instrukcijų vykdymo planuokliai, įvairūs buferiai ir kt., kurie užima vietą luste. Visa tai būtina norint pasiekti geriausią veikimą vienos sriegio režimu.

Tačiau GPU visa tai nėra būtina, jis yra architektūriškai greitesnis atliekant skaičiavimo užduotis su daugybe gijų. Vietoj to, jis paverčia daugiasriegiu būdu į spektaklį, kaip filosofinis akmuo paverčia šviną auksu.

GPU iš pradžių buvo sukurtas taip, kad optimaliai vykdytų trikampių pikselių šešėliavimo programas, kurios akivaizdžiai yra nepriklausomos ir gali būti vykdomos lygiagrečiai. Ir iš šios būsenos jis išsivystė pridedant įvairias funkcijas (vietinę atmintį ir adresuojamą prieigą prie vaizdo atminties, taip pat apsunkinant instrukcijų rinkinį) į labai galingą skaičiavimo įrenginį, kuris vis dar gali būti efektyviai pritaikytas tik algoritmams, kurie leidžia labai lygiagrečiai įgyvendinti. naudojant ribotą vietinės atminties kiekį.atmintis.

Pavyzdys

Viena iš klasikinių GPU problemų yra N kūnų, sukuriančių gravitacinį lauką, sąveikos skaičiavimo problema. Bet jei, pavyzdžiui, reikia skaičiuoti sistemos Žemė-Mėnulis-Saulė evoliuciją, tai GPU mums yra blogas pagalbininkas: objektų mažai. Kiekvienam objektui reikia apskaičiuoti sąveiką su visais kitais objektais, o jų yra tik du. Saulės sistemos judėjimo su visomis planetomis ir jų palydovais (apie porą šimtų objektų) atveju GPU vis tiek nėra labai efektyvus. Tačiau kelių branduolių procesorius dėl didelių pridėtinių sąnaudų gijų valdymui taip pat negalės parodyti visos savo galios, veiks vienos gijos režimu. Bet jei taip pat reikia apskaičiuoti kometų ir asteroidų juostos objektų trajektorijas, tai jau yra GPU užduotis, nes objektų yra pakankamai, kad būtų sukurtas reikiamas lygiagrečių skaičiavimo gijų skaičius.

GPU taip pat gerai veiks, jei reikės apskaičiuoti šimtų tūkstančių žvaigždžių rutulinių spiečių susidūrimą.

Kita galimybė panaudoti GPU galią sprendžiant N korpuso problemą atsiranda tada, kai reikia apskaičiuoti daug individualių problemų, nors ir su nedideliu korpusų skaičiumi. Pavyzdžiui, jei norite apskaičiuoti vienos sistemos raidą skirtingoms pradinio greičio parinktims. Tada bus galima efektyviai naudoti GPU be problemų.

AMD Radeon mikroarchitektūros detalės

Mes apsvarstėme pagrindinius GPU organizavimo principus, jie yra įprasti visų gamintojų vaizdo greitintuvams, nes iš pradžių jie turėjo vieną tikslinę užduotį - šešėlių programas. Tačiau gamintojai pastebėjo, kad galima nesutarti dėl mikroarchitektūrinio įgyvendinimo detalių. Nors skirtingų tiekėjų CPU kartais labai skiriasi, net jei jie yra suderinami, pvz., Pentium 4 ir Athlon arba Core. „Nvidia“ architektūra jau plačiai žinoma, dabar pažvelgsime į „Radeon“ ir išryškinsime pagrindinius šių pardavėjų požiūrių skirtumus.

AMD vaizdo plokštės gavo visišką bendrosios paskirties skaičiavimo palaikymą nuo Evergreen šeimos, kuri taip pat buvo DirectX 11 specifikacijos pradininkė. 47xx šeimos plokštės turi keletą reikšmingų apribojimų, kurie bus aptarti toliau.

Vietinės atminties dydžio skirtumai (32 KB Radeon ir 16 KB GT200 ir 64 KB Fermi) paprastai nėra esminiai. Taip pat bangos fronto dydis yra 64 gijos AMD, palyginti su 32 gijomis viename Nvidia. Beveik bet kurią GPU programą galima lengvai perkonfigūruoti ir pritaikyti prie šių parametrų. Našumas gali pasikeisti dešimtimis procentų, tačiau GPU atveju tai nėra taip svarbu, nes GPU programa dažniausiai veikia dešimt kartų lėčiau nei jos atitikmuo CPU, arba dešimt kartų greičiau, arba neveikia visai.

Svarbiau yra naudojimas AMD technologijos VLIW (labai ilgas instrukcijos žodis). Nvidia naudoja skaliarines paprastas instrukcijas, kurios veikia skaliariniuose registruose. Jo greitintuvai įgyvendina paprastą klasikinį RISC. AMD vaizdo plokštės turi tiek pat registrų kaip GT200, tačiau registrai yra 128 bitų vektoriniai. Kiekviena VLIW instrukcija veikia keliuose keturių komponentų 32 bitų registruose, kurie yra panašūs į SSE, tačiau VLIW galimybės yra daug platesnės. Tai nėra SIMD (Single Instruction Multiple Data), kaip SSE – čia kiekvienos operandų poros instrukcijos gali būti skirtingos ir netgi priklausomos! Pavyzdžiui, registro A komponentai bus pavadinti a1, a2, a3, a4; B registrui – panašiai. Galima apskaičiuoti naudojant vieną komandą, kuri vykdoma per vieną ciklą, pavyzdžiui, skaičius a1×b1+a2×b2+a3×b3+a4×b4 arba dvimatis vektorius (a1×b1+a2×b2, a3× b3+a4×b4).

Tai tapo įmanoma dėl mažesnio GPU dažnio nei procesoriaus ir smarkiai sumažinus techninius procesus pastaraisiais metais. Tam nereikia jokio planavimo, beveik viskas vykdoma pagal laikrodį.

Naudojant vektorines instrukcijas, Radeon didžiausias vieno tikslumo našumas yra labai didelis, esant teraflopams.

Viename vektoriniame registre vietoj keturių pavienių tikslumo skaičių galima saugoti vieną dvigubą tikslumo skaičių. Ir viena VLIW instrukcija gali arba pridėti dvi poras dublių, arba padauginti du skaičius, arba padauginti du skaičius ir pridėti prie trečiojo. Taigi didžiausias našumas dvigubai yra maždaug penkis kartus mažesnis nei plūduriuojant. Senesniems Radeon modeliams tai atitinka Nvidia našumas Tesla su nauja Fermi architektūra ir daug didesniu našumu nei dvigubos kortelės GT200 architektūroje. Vartotojų „Geforce“ vaizdo plokštėse, pagrįstose „Fermi“, didžiausia dvigubo skaičiavimo sparta buvo sumažinta keturis kartus.


Scheminė Radeono darbo schema. Rodomas tik vienas miniprocesorius iš 20 lygiagrečiai veikiančių

GPU gamintojai, skirtingai nei CPU gamintojai (visų pirma, suderinami su x86), nėra saistomi suderinamumo problemų. GPU programa pirmiausia sukompiliuojama į tam tikrą tarpinį kodą, o kai programa paleidžiama, tvarkyklė sukompiliuoja šį kodą į mašinos instrukcijas, skirtas konkrečiai konkretus modelis. Kaip aprašyta aukščiau, GPU gamintojai tuo pasinaudojo išradę patogią ISA (instrukcijų rinkinio architektūrą) savo GPU ir keisdami juos iš kartos į kartą. Bet kokiu atveju tai padidino našumo procentą dėl dekoderio trūkumo (kaip nereikalingo). Tačiau AMD nuėjo dar toliau, išrasdama savo formatą, skirtą instrukcijoms tvarkyti mašininiame kode. Jie išdėstyti ne nuosekliai (pagal programų sąrašą), o skyriais.

Pirmiausia atsiranda sąlyginių peršokimų instrukcijų skyrius, turintis nuorodas į ištisinių aritmetinių instrukcijų skyrius, atitinkančius skirtingas šakų šakas. Jie vadinami VLIW paketais (VLIW instrukcijų paketais). Šiuose skyriuose yra tik aritmetinės instrukcijos su duomenimis iš registrų arba vietinės atminties. Tokia organizacija supaprastina instrukcijų srautą ir jų pristatymą vykdymo padaliniams. Tai dar naudingiau, nes VLIW instrukcijos yra gana didelės. Taip pat yra skyriai, skirti prieigos prie atminties instrukcijoms.

Sąlyginės šakos instrukcijos skyriai
0 skyriusIšsišakojimas 0Nuoroda į ištisinių aritmetinių nurodymų 3 skyrių
1 skyriusIšsišakojimas 1Nuoroda į 4 skyrių
2 skyrius2 išsišakojimasNuoroda į 5 skyrių
Tęstinių aritmetinių nurodymų skyriai
3 skyriusVLIW instrukcija 0VLIW instrukcija 1VLIW instrukcija 2VLIW instrukcija 3
4 skyriusVLIW instrukcija 4VLIW instrukcija 5
5 skyriusVLIW instrukcija 6VLIW instrukcija 7VLIW instrukcija 8VLIW instrukcija 9

Abiejų gamintojų GPU (tiek Nvidia, tiek AMD) taip pat turi įmontuotas instrukcijas, skirtas greitai apskaičiuoti pagrindines matematines funkcijas, kvadratinę šaknį, eksponentą, logaritmus, sinusus ir kosinusus pavieniams tiksliams skaičiams per kelis ciklus. Tam yra specialūs skaičiavimo blokai. Jie „atsirado“ dėl poreikio greitai pritaikyti šias funkcijas geometrijos šešėliuose.

Net jei kas nors nežinojo, kad grafikai naudojami GPU, o tik susipažino su techninėmis charakteristikomis, tai pagal šį ženklą galėjo spėti, kad šie skaičiavimo koprocesoriai atsirado iš vaizdo greitintuvų. Panašiai kai kurie jūrų žinduolių bruožai paskatino mokslininkus manyti, kad jų protėviai buvo sausumos būtybės.

Tačiau akivaizdesnė funkcija, parodanti grafinę įrenginio kilmę, yra dvimačių ir trimačių tekstūrų skaitymo blokai, palaikantys bilinijinę interpoliaciją. Jie plačiai naudojami GPU programose, nes užtikrina greitesnį ir lengvesnį tik skaitomų duomenų masyvų skaitymą. Vienas iš standartinės parinktys GPU programa nuskaito pradinių duomenų masyvus, apdoroja juos skaičiavimo branduoliuose ir įrašo rezultatą į kitą masyvą, kuris vėliau perkeliamas atgal į centrinį procesorių. Tokia schema yra standartinė ir įprasta, nes ji yra patogi GPU architektūrai. Užduotis, kurioms reikalingas intensyvus skaitymas ir įrašymas į vieną didelę pasaulinės atminties sritį, todėl jose yra duomenų priklausomybės, sunku lygiagretinti ir efektyviai įgyvendinti GPU. Be to, jų našumas labai priklausys nuo pasaulinės atminties delsos, kuri yra labai didelė. Bet jei užduotį apibūdina šablonas „duomenų skaitymas – apdorojimas – rezultato rašymas“, tuomet beveik neabejotinai gausite didelį postūmį jos vykdymui GPU.

Tekstūros duomenims GPU yra atskira pirmojo ir antrojo lygių mažų talpyklų hierarchija. Tai taip pat suteikia pagreitį naudojant tekstūras. Ši hierarchija iš pradžių atsirado GPU, siekiant pasinaudoti prieigos prie tekstūrų vietove: akivaizdu, kad apdorojus vieną pikselį, kaimyniniam pikseliui (su didele tikimybe) reikės glaudžiai išdėstytų tekstūros duomenų. Tačiau daugelis įprastinio skaičiavimo algoritmų turi panašų prieigos prie duomenų pobūdį. Taigi tekstūros talpyklos iš grafikos bus labai naudingos.

Nors L1-L2 talpyklų dydis Nvidia ir AMD kortelėse yra maždaug vienodas, o tai akivaizdžiai nulemia optimalumo reikalavimai žaidimo grafikai, prieigos prie šių talpyklų delsa gerokai skiriasi. „Nvidia“ prieigos delsa yra didesnė, o „Geforce“ tekstūros talpyklos pirmiausia padeda sumažinti atminties magistralės apkrovą, o ne tiesiogiai pagreitina duomenų prieigą. Grafikos programose tai nepastebima, bet svarbu bendrosios paskirties programoms. Radeone tekstūros talpyklos delsa yra mažesnė, tačiau mini procesorių vietinės atminties vėlavimas yra didesnis. Štai pavyzdys: optimaliam matricos dauginimui Nvidia kortelėse geriau naudoti vietinę atmintį, ten įkeliant matricą blokas po bloko, o AMD atveju geriau pasikliauti mažos delsos tekstūros talpykla, nuskaitant matricos elementus kaip reikia. Bet tai jau gana subtilus optimizavimas ir algoritmui, kuris jau iš esmės buvo perkeltas į GPU.

Šis skirtumas taip pat išryškėja naudojant 3D tekstūras. Vienas iš pirmųjų GPU skaičiavimo etalonų, parodęs rimtą AMD pranašumą, tiesiog naudojo 3D tekstūras, nes dirbo su trimačiu duomenų masyvu. O „Radeon“ tekstūros prieigos delsa yra žymiai greitesnė, o 3D korpusas papildomai labiau optimizuotas aparatinėje įrangoje.

Norint gauti maksimalų įvairių įmonių aparatinės įrangos našumą, reikia šiek tiek suderinti konkrečios kortelės programą, tačiau tai yra daug mažiau reikšminga nei iš esmės GPU architektūros algoritmo kūrimas.

„Radeon 47xx“ serijos apribojimai

Šioje šeimoje GPU skaičiavimo palaikymas yra neišsamus. Yra trys svarbias akimirkas. Pirma, nėra vietinės atminties, tai yra, ji yra fiziškai, bet neturi visuotinės prieigos, kurios reikalauja šiuolaikinis GPU programų standartas. Jis programiškai emuliuojamas pasaulinėje atmintyje, o tai reiškia, kad jo naudojimas nebus naudingas, o ne visas funkcijas turintis GPU. Antras punktas yra ribotas įvairių atominės atminties operacijų ir sinchronizavimo instrukcijų palaikymas. Ir trečias punktas yra gana mažas dydis instrukcijų talpykla: pradedant nuo tam tikro dydžio programos, greitis kelis kartus sulėtėja. Taip pat yra ir kitų nedidelių apribojimų. Galime pasakyti, kad šioje vaizdo plokštėje gerai veiks tik tos programos, kurios idealiai tinka GPU. Nors vaizdo plokštė gali parodyti gerus Gigaflops rezultatus paprastose testavimo programose, veikiančiose tik su registrais, jai sudėtinga efektyviai suprogramuoti kažką sudėtingo.

Evergreen privalumai ir trūkumai

Jei palygintume AMD ir Nvidia gaminius, tai GPU skaičiavimo prasme 5xxx serija atrodo kaip labai galingas GT200. Toks galingas, kad savo didžiausiu našumu aplenkia Fermi maždaug du su puse karto. Ypač apkarpius naujųjų Nvidia vaizdo plokščių parametrus, sumažėjo branduolių skaičius. Tačiau L2 talpyklos atsiradimas „Fermi“ supaprastina kai kurių algoritmų įgyvendinimą GPU, taip išplečiant GPU apimtį. Įdomu tai, kad gerai optimizuotoms ankstesnės kartos GT200 CUDA programoms Fermi architektūrinės naujovės dažnai nieko nedavė. Jie pagreitėjo proporcingai skaičiavimo modulių skaičiaus didėjimui, tai yra mažiau nei du kartus (pavieniams tiksliams skaičiams) arba net mažiau, nes atminties pralaidumas nepadidėjo (ar dėl kitų priežasčių).

Ir atliekant užduotis, kurios puikiai tinka GPU architektūrai ir turi ryškų vektorinį pobūdį (pavyzdžiui, matricos dauginimas), „Radeon“ rodo našumą palyginti artimą teoriniam pikui ir aplenkia „Fermi“. Jau nekalbant apie kelių branduolių procesorius. Ypač problemose su pavieniais tikslumo skaičiais.

Tačiau „Radeon“ turi mažesnį štampo plotą, mažesnį šilumos išsklaidymą, energijos suvartojimą, didesnį derlių ir atitinkamai mažesnę kainą. Ir tiesiogiai 3D grafikos problemose Fermi stiprinimas, jei toks yra, yra daug mažesnis nei kristalo ploto skirtumas. Taip yra daugiausia dėl to, kad „Radeon“ skaičiavimo architektūra, turinti 16 skaičiavimo vienetų viename miniprocesoriuje, 64 gijų bangų frontą ir VLIW vektorines instrukcijas, puikiai tinka pagrindinei jo užduočiai – grafinių atspalvių skaičiavimui. Didžiajai daugumai paprasti vartotojaižaidimų našumas ir kaina yra prioritetas.

Profesionalių, mokslinių programų požiūriu, Radeon architektūra užtikrina geriausią kainos ir našumo santykį, našumą vienam vatui ir absoliutų našumą atliekant užduotis, kurios iš esmės gerai dera su GPU architektūra, leidžia lygiagrečiai ir vektorizuoti.

Pavyzdžiui, visiškai lygiagrečios, lengvai vektorizuojamos raktų pasirinkimo problemos atveju „Radeon“ yra kelis kartus greitesnis nei „Geforce“ ir kelias dešimtis kartų greitesnis už procesorių.

Tai atitinka bendrą AMD Fusion koncepciją, pagal kurią GPU turėtų papildyti centrinį procesorių, o ateityje integruotis į patį procesoriaus šerdį, kaip anksčiau matematinis koprocesorius buvo perkeltas iš atskiro lusto į procesoriaus branduolį (taip nutiko apie prieš dvidešimt metų, prieš pasirodant pirmiesiems Pentium procesoriams). GPU bus integruotas grafikos branduolys ir vektorinį koprocesorių srautinio perdavimo užduotims atlikti.

„Radeon“ naudoja sudėtingą techniką maišyti instrukcijas iš skirtingų bangų frontų, kai jas vykdo funkciniai moduliai. Tai lengva padaryti, nes instrukcijos yra visiškai nepriklausomos. Principas panašus į konvejerinį nepriklausomų instrukcijų vykdymą šiuolaikiniais procesoriais. Matyt, tai leidžia efektyviai vykdyti sudėtingas, kelių baitų, vektorines VLIW komandas. CPU tam reikalingas sudėtingas planuoklis, kad būtų galima nustatyti nepriklausomas instrukcijas, arba naudoti Hyper-Threading technologiją, kuri taip pat tiekia CPU žinomomis nepriklausomomis instrukcijomis iš skirtingų gijų.

matuoti 01 priemonė2 priemonė3 priemonėbaras 45 priemonė6 priemonė7 priemonėVLIW modulis
bangos frontas 0bangos frontas 1bangos frontas 0bangos frontas 1bangos frontas 0bangos frontas 1bangos frontas 0bangos frontas 1
instr. 0instr. 0instr. 16instr. 16instr. 32instr. 32instr. 48instr. 48VLIW0
instr. vienasVLIW1
instr. 2VLIW2
instr. 3VLIW3
instr. keturiVLIW4
instr. 5VLIW5
instr. 6VLIW6
instr. 7VLIW7
instr. aštuoniVLIW8
instr. 9VLIW9
instr. dešimtVLIW10
instr. vienuolikaVLIW11
instr. 12VLIW12
instr. 13VLIW13
instr. keturiolikaVLIW14
instr. penkiolikaVLIW15

16 VLIW modulių aštuoniais ciklais vykdo 128 instrukcijas iš dviejų bangų frontų, kurių kiekvieną sudaro 64 operacijos. Yra kaita, ir kiekvienas modulis iš tikrųjų turi du ciklus visai komandai vykdyti, jei antrajame cikle jis pradeda vykdyti lygiagrečiai naują. Tai tikriausiai padeda greitai įvykdyti VLIW komandą, pvz., a1 × a2 + b1 × b2 + c1 × c2 + d1 × d2, ty atlikti aštuonias tokias komandas aštuoniais ciklais. (Pasirodo, formaliai, po vieną per laikrodį.)

Nvidia, matyt, neturi šios technologijos. O jei nėra VLIW, didelis našumas naudojant skaliarines instrukcijas reikalauja didelio veikimo dažnio, o tai automatiškai padidina šilumos išsklaidymą ir kelia didelius reikalavimus procesui (priversti grandinę veikti didesniu dažniu).

Radeon trūkumas, kalbant apie GPU skaičiavimą, yra didelis nemėgimas išsišakojimui. GPU paprastai neteikia pirmenybės išsišakojimui dėl aukščiau nurodytos instrukcijų vykdymo technologijos: iškart gijų grupe su vienu programos adresu. (Beje, ši technika vadinama SIMT: Single Instruction - Multiple Threads (viena instrukcija - daug gijų), pagal analogiją su SIMD, kai viena instrukcija atlieka vieną operaciją su skirtingais duomenimis.) . Akivaizdu, kad jei programa nėra visiškai vektorinė, tai kuo didesnis metmenų arba bangos fronto dydis, tuo blogiau, nes kai kelias per programą skiriasi, susidaro gretimos gijos. daugiau grupių, kuris turi būti vykdomas nuosekliai (serializuotas). Tarkime, kad visos gijos išsisklaidė, tada, kai metmenų dydis yra 32 gijos, programa veiks 32 kartus lėčiau. O 64 dydžio atveju, kaip ir Radeon, jis yra 64 kartus lėtesnis.

Tai pastebima, bet ne vienintelė „nepatinka“ apraiška. Nvidia vaizdo plokštėse kiekvienas funkcinis modulis, kitaip vadinamas CUDA branduoliu, turi specialų atšaką apdorojimo bloką. O „Radeon“ vaizdo plokštėse, skirtose 16 skaičiavimo modulių, yra tik du išsišakoję valdymo blokai (jie yra kilę iš aritmetinių vienetų srities). Taigi net paprastas sąlyginės šakos instrukcijos apdorojimas, net jei jos rezultatas yra vienodas visoms bangos fronto gijomis, užtrunka papildomai. Ir greitis krenta.

AMD taip pat gamina CPU. Jie mano, kad programoms, turinčioms daug šakų, CPU vis tiek geriau tinka, o GPU skirtas grynai vektorinėms programoms.

Taigi „Radeon“ teikia mažiau efektyvų programavimą, tačiau daugeliu atvejų geresnį kainos ir kokybės santykį. Kitaip tariant, yra mažiau programų, kurias galima efektyviai (naudingai) perkelti iš procesoriaus į „Radeon“, nei programų, kurias galima efektyviai paleisti „Fermi“. Tačiau, kita vertus, tie, kuriuos galima efektyviai perkelti, daugeliu atžvilgių veiks efektyviau „Radeon“.

API, skirta GPU skaičiavimui

patys Techninės specifikacijos Radeon atrodo patraukliai, net jei nereikia idealizuoti ir suabsoliutinti GPU skaičiavimo. Tačiau ne mažiau svarbi našumui yra programinė įranga, reikalinga GPU programai kurti ir vykdyti – kompiliatoriai iš aukšto lygio kalbos ir vykdymo laiko, tai yra tvarkyklė, kuri sąveikauja tarp CPU veikiančios programos dalies ir GPU. pats. Tai dar svarbiau nei procesoriaus atveju: CPU nereikia tvarkyklės duomenų perdavimui valdyti, o kompiliatoriaus požiūriu GPU yra sudėtingesnis. Pavyzdžiui, kompiliatorius turi apsieiti su minimaliu registrų skaičiumi, kad saugotų tarpinius skaičiavimo rezultatus, taip pat tvarkingai įterptus funkcijų iškvietimus, vėlgi naudodamas minimalų registrų skaičių. Galų gale, kuo mažiau registrų gija naudoja, tuo daugiau gijų galite paleisti ir kuo pilniau įkelti GPU, geriau paslepiant prieigos prie atminties laiką.

Taigi „Radeon“ produktų programinės įrangos palaikymas vis dar atsilieka nuo aparatinės įrangos kūrimo. (Priešingai nei „Nvidia“ atveju, kai aparatinės įrangos išleidimas buvo atidėtas, o produktas buvo išleistas supaprastinta forma.) Visai neseniai AMD „OpenCL“ kompiliatorius buvo beta versijos būsenoje ir turėjo daug trūkumų. Ji per dažnai generuodavo klaidingą kodą arba atsisakė kompiliuoti kodą iš teisingo šaltinio kodo arba pati davė klaidą ir sudužo. Tik pavasario pabaigoje pasirodė didelio našumo leidimas. Tai taip pat neapsieina be klaidų, tačiau jų yra žymiai mažiau, ir jos, kaip taisyklė, atsiranda nuošalyje, kai bandoma kažką programuoti ties teisingumo riba. Pavyzdžiui, jie veikia su uchar4 tipu, kuris nurodo 4 baitų keturių komponentų kintamąjį. Šis tipas yra „OpenCL“ specifikacijose, bet „Radeon“ su juo dirbti neapsimoka, nes registrai yra 128 bitų: tie patys keturi komponentai, bet 32 ​​bitų. Ir toks uchar4 kintamasis vis tiek užims visą registrą, tik dar reikės papildomų pakavimo ir prieigos prie atskirų baitų komponentų operacijų. Kompiliatorius neturėtų turėti klaidų, bet nėra kompiliatorių be klaidų. Net „Intel Compiler“ po 11 versijų turi kompiliavimo klaidų. Nustatytos klaidos ištaisytos kitame leidime, kuris bus išleistas arčiau rudens.

Tačiau dar yra daug dalykų, kuriuos reikia patobulinti. Pavyzdžiui, iki šiol standartinė Radeon GPU tvarkyklė nepalaiko GPU skaičiavimo naudojant OpenCL. Vartotojas turi atsisiųsti ir įdiegti papildomą specialų paketą.

Tačiau svarbiausia, kad nėra jokių funkcijų bibliotekų. Dvigubo tikslumo realiesiems skaičiams net nėra sinuso, kosinuso ir laipsnio. Na, tai nėra būtina matricos sudėjimui/daugybai, bet jei norite užprogramuoti ką nors sudėtingesnio, turite rašyti visas funkcijas nuo nulio. Arba palaukite naujo SDK leidimo. ACML netrukus bus išleistas ( AMD branduolys Matematikos biblioteka), skirta Evergreen GPU šeimai, palaikanti pagrindines matricos funkcijas.

Šiuo metu, anot straipsnio autorės, „Direct Compute 5.0“ API naudojimas programuojant „Radeon“ vaizdo plokštes atrodo realus, natūraliai atsižvelgiant į apribojimus: orientaciją į „Windows 7“ platformą ir Windows Vista. „Microsoft“ turi daug patirties kuriant kompiliatorius, ir netrukus galime tikėtis visiškai veikiančios laidos, „Microsoft“ tuo domisi. Tačiau „Direct Compute“ yra orientuota į interaktyvių programų poreikius: ką nors apskaičiuoti ir iškart vizualizuoti rezultatą – pavyzdžiui, skysčio tekėjimą paviršiumi. Tai nereiškia, kad jis negali būti naudojamas tiesiog skaičiavimams, tačiau tai nėra natūrali jo paskirtis. Pavyzdžiui, „Microsoft“ neplanuoja pridėti bibliotekos funkcijų prie „Direct Compute“ – būtent tokių, kurių šiuo metu AMD neturi. Tai yra, tai, ką dabar galima efektyviai apskaičiuoti „Radeon“ – kai kurios nelabai sudėtingos programos – taip pat gali būti įdiegta „Direct Compute“, kuri yra daug paprastesnė nei „OpenCL“ ir turėtų būti stabilesnė. Be to, jis yra visiškai nešiojamas ir veiks ir Nvidia, ir AMD, todėl programą turėsite kompiliuoti tik vieną kartą, o Nvidia ir AMD OpenCL SDK diegimai nėra tiksliai suderinami. (Ta prasme, kad jei kuriate OpenCL programą AMD sistemoje naudodami AMD OpenCL SDK, ji gali ne taip lengvai veikti Nvidia. Gali tekti kompiliuoti tą patį tekstą naudojant Nvidia SDK. Ir, žinoma, atvirkščiai. )

Tada OpenCL yra daug perteklinių funkcijų, nes OpenCL yra universali programavimo kalba ir API įvairioms sistemoms. Ir GPU, ir CPU, ir Cell. Taigi, jei norite tiesiog parašyti programą tipinei vartotojo sistemai (procesorius ir vaizdo plokštė), „OpenCL“ neatrodo, taip sakant, „labai produktyvi“. Kiekviena funkcija turi dešimt parametrų, o devyni iš jų turi būti 0. O norint nustatyti kiekvieną parametrą, reikia iškviesti specialią funkciją, kuri taip pat turi parametrus.

O svarbiausias dabartinis „Direct Compute“ privalumas yra tas, kad vartotojui nereikia diegti specialaus paketo: viskas, ko reikia, jau yra „DirectX 11“.

GPU skaičiavimo kūrimo problemos

Jei imtume asmeninių kompiuterių sritį, situacija tokia: daug skaičiavimo galios reikalaujančių užduočių, kurių labai trūksta įprastiniam dviejų branduolių procesoriui, nėra daug. Iš jūros į sausumą tarsi išropojo dideli rijingi, bet nerangūs monstrai, o sausumoje beveik nebuvo ką valgyti. O pirmykštės žemės paviršiaus buveinės mažėja, mokosi vartoti mažiau, kaip visada nutinka, kai pritrūksta gamtos išteklių. Jei šiandien būtų toks pat našumo poreikis kaip prieš 10–15 metų, GPU skaičiavimas būtų priimtas su kaupu. Taigi išryškėja suderinamumo ir santykinio GPU programavimo sudėtingumo problemos. Geriau rašyti programą, kuri veikia visose sistemose, nei greitą, bet tik GPU veikiančią programą.

GPU perspektyvos yra šiek tiek geresnės, kalbant apie naudojimą profesionaliose programose ir darbo stočių sektoriuje, nes yra didesnė našumo paklausa. Atsiranda GPU palaikančių 3D redaktorių įskiepiai: pavyzdžiui, atvaizdavimui naudojant spindulių sekimą – nereikia painioti su įprastu GPU atvaizdavimu! Taip pat kažkas rodoma 2D ir pristatymų redaktoriams, nes greičiau sukuriami sudėtingi efektai. Vaizdo įrašų apdorojimo programos taip pat palaipsniui įgyja GPU palaikymą. Minėtos užduotys, atsižvelgiant į jų paralelinį pobūdį, puikiai tinka GPU architektūrai, tačiau dabar sukurta labai didelė kodų bazė, derinama, optimizuota visoms procesoriaus galimybėms, todėl prireiks laiko, kol pasirodys geri GPU diegimai.

Šiame segmente pasireiškia ir tokie GPU trūkumai, kaip ribotas vaizdo atminties kiekis – apie 1 GB įprastiniams GPU. Vienas pagrindinių faktorių, mažinančių GPU programų našumą, yra būtinybė keistis duomenimis tarp procesoriaus ir GPU per lėtą magistralę, o dėl riboto atminties kiekio reikia perduoti daugiau duomenų. Ir štai AMD koncepcija sujungti GPU ir procesorių viename modulyje atrodo daug žadanti: galite paaukoti didelį grafinės atminties pralaidumą, kad galėtumėte lengvai ir paprastai pasiekti bendrąją atmintį, be to, su mažesne delsa. Šis didelis dabartinės DDR5 vaizdo atminties pralaidumas yra daug paklausesnis grafines programas nei dauguma GPU skaičiavimo programų. Apskritai, Bendra atmintis GPU ir centrinis procesorius tiesiog žymiai išplės GPU apimtį, leis panaudoti jo skaičiavimo galimybes atliekant mažas programų papildomas užduotis.

Ir daugiausia GPU yra paklausūs mokslinio skaičiavimo srityje. Jau pastatyti keli GPU pagrindu veikiantys superkompiuteriai, kurie matricinių operacijų teste rodo labai aukštus rezultatus. Mokslinės problemos yra tokios įvairios ir daugybės, kad visada yra rinkinys, puikiai tinkantis GPU architektūrai, kuriam naudojant GPU lengva pasiekti aukštą našumą.

Jei pasirinksite vieną iš visų šiuolaikinių kompiuterių užduočių, tai bus kompiuterinė grafika - pasaulio, kuriame gyvename, vaizdas. O šiam tikslui optimali architektūra negali būti bloga. Tai tokia svarbi ir esminė užduotis, kad specialiai jai sukurta techninė įranga turi būti universali ir optimali įvairioms užduotims atlikti. Be to, vaizdo plokštės sėkmingai tobulėja.

Vienas is labiausiai paslėptų savybių, naujausiame „Windows 10“ naujinime yra galimybė patikrinti, kurios programos naudoja jūsų grafikos apdorojimo bloką (GPU). Jei kada nors atidarėte užduočių tvarkyklę, tikriausiai peržiūrėjote procesoriaus naudojimą, kad sužinotumėte, kurios programos naudoja daugiausiai procesoriaus. AT Naujausi Atnaujinimai pridėjo panašią funkciją, bet skirtą GPU GPU. Tai padeda suprasti, kaip intensyviai veikia jūsų GPU programinė įranga ir žaidimai, neatsisiunčiant trečiosios šalies programinės įrangos. Yra dar viena įdomi funkcija, padedanti iškrauti jūsų procesorių į GPU. Rekomenduoju paskaityti kaip išsirinkti.

Kodėl užduočių tvarkytuvėje neturiu GPU?

Deja, ne visos vaizdo plokštės galės pateikti Windows statistiką, reikalingą GPU nuskaityti. Norėdami įsitikinti, galite greitai naudoti „DirectX“ diagnostikos įrankį, kad išbandytumėte šią technologiją.

  1. spustelėkite " Pradėti“ ir paieškoje parašykite dxdiag Norėdami paleisti „DirectX“ diagnostikos įrankį.
  2. Eiti į skirtuką " Ekranas“, tiesiai stulpelyje vairuotojai"tu turėtum turėti WDDM modelis didesnę nei 2.0 versiją, kad galėtumėte naudoti GPU grafikus užduočių tvarkyklėje.

Įgalinkite GPU grafiką užduočių tvarkyklėje

Norėdami pamatyti kiekvienos programos GPU naudojimą, turite atidaryti užduočių tvarkyklę.

  • Paspauskite mygtukų kombinaciją Ctrl + Shift + Esc Norėdami atidaryti užduočių tvarkyklę.
  • Spustelėkite dešiniuoju pelės mygtuku spustelėkite spustelėkite užduočių tvarkytuvę tuščiame lauke " Vardas" ir patikrinkite išskleidžiamajame meniu GPU. Taip pat galite pažymėti GPU branduolys kad pamatytumėte, kurios programos jį naudoja.
  • Dabar užduočių tvarkyklėje GPU grafikas ir GPU branduolys matomi dešinėje.


Peržiūrėkite bendrą GPU našumą

Galite stebėti bendrą GPU naudojimą, kad galėtumėte stebėti ir analizuoti esant didelėms apkrovoms. Tokiu atveju viską, ko jums reikia, galite pamatyti „ Spektaklis“ pasirinkdami grafikos procesorius.


Kiekvienas GPU elementas yra suskirstytas į atskiras diagramas, kad galėtumėte dar geriau suprasti, kaip naudojamas jūsų GPU. Jei norite pakeisti rodomas diagramas, galite spustelėti mažą rodyklę šalia kiekvienos užduoties pavadinimo. Šiame ekrane taip pat rodoma jūsų tvarkyklės versija ir data, kuri yra gera alternatyva naudojant „DXDiag“ arba „Device Manager“.


branduolių niekada nebūna per daug...

Šiuolaikiniai GPU yra nepaprastai greiti žvėrys, galintys sukramtyti gigabaitus duomenų. Tačiau žmogus yra gudrus ir, nesvarbu, kaip auga skaičiavimo galia, atsiranda vis sunkesnių užduočių, tad ateina momentas, kai tenka su liūdesiu konstatuoti, kad optimizuoti reikia 🙁

Šiame straipsnyje aprašomos pagrindinės sąvokos, kad būtų lengviau naršyti GPU optimizavimo teorijoje ir pagrindinėse taisyklėse, kad šios sąvokos būtų prieinamos rečiau.

Priežastys, kodėl GPU yra veiksmingi sprendžiant didelius duomenų kiekius, kuriuos reikia apdoroti:

  • jie turi puikias galimybes lygiagrečiai vykdyti užduotis (daug, daug procesorių)
  • didelis atminties pralaidumas

Atminties pralaidumas– tiek informacijos – bitų ar gigabaitų – galima perduoti per laiko vienetą, sekundę ar procesoriaus ciklą.

Viena iš optimizavimo užduočių yra išnaudoti didžiausią pralaidumą – padidinti našumą pralaidumas(idealiu atveju jis turėtų būti lygus atminties pralaidumui).

Norėdami pagerinti pralaidumo naudojimą:

  • padidinti informacijos kiekį – išnaudoti visą pralaidumą (pavyzdžiui, kiekvienas srautas veikia su float4)
  • sumažinti delsą – delsą tarp operacijų

Latencija- laiko intervalas tarp momentų, kai valdiklis paprašė konkrečios atminties ląstelės, ir momento, kai duomenys tapo prieinami procesoriui, kad galėtų vykdyti komandas. Negalime niekaip įtakoti pačio vėlavimo – šie apribojimai yra aparatinės įrangos lygmenyje. Dėl šio delsimo procesorius vienu metu gali aptarnauti kelias gijas – kol gija A prašė skirti jai atminties, gija B gali ką nors apskaičiuoti, o gija C gali laukti, kol ateis prašomi duomenys.

Kaip sumažinti delsą, jei naudojamas sinchronizavimas:

  • sumažinti siūlų skaičių bloke
  • padidinti blokų grupių skaičių

Visiškas GPU išteklių naudojimas – GPU užimtumas

Populiariuose pokalbiuose apie optimizavimą terminas dažnai mirksi - GPU užimtumas arba branduolio užimtumas- tai atspindi vaizdo plokštės išteklių-pajėgumų panaudojimo efektyvumą. Atskirai pažymiu, kad net jei naudojate visus išteklius, tai nereiškia, kad juos naudojate teisingai.

GPU skaičiavimo galia yra šimtai procesorių godžiai skaičiavimams, kuriant programą - branduolį (brandulį) - našta paskirstyti jiems tenkančią apkrovą krenta ant programuotojo pečių. Dėl klaidos dauguma šių brangių išteklių gali būti nenaudojami be jokios priežasties. Dabar paaiškinsiu kodėl. Pradėti reikia iš toli.

Leiskite jums priminti, kad metmenys ( metmenys NVidia terminologijoje, bangos frontas - AMD terminologija) - gijų rinkinys, kuris tuo pačiu metu atlieka tą pačią procesoriaus branduolio funkciją. Gijas, kurias programuotojas sujungs į blokus, gijų planuoklis suskirsto į metmenis (kiekvienam daugiaprocesoriui atskirai) – kol veikia vienas metmenys, antrasis laukia, kol bus apdoroti atminties užklausos ir pan. Jei kai kurios metmenų gijos vis dar atlieka skaičiavimus, o kitos jau padarė viską, ką galėjo, tada yra neefektyvus skaičiavimo resursų naudojimas – liaudiškai vadinamas tuščiosios eigos galia.

Kiekvienas sinchronizacijos taškas, kiekviena logikos šaka gali sukurti tokią tuščią padėtį. Didžiausias nukrypimas (vykdymo logikos išsišakojimas) priklauso nuo metmenų dydžio. NVidia GPU tai yra 32, AMD - 64.

Norėdami sumažinti kelių procesorių prastovą vykdant deformaciją:

  • sumažinti laukimo laiko kliūtis
  • sumažinti branduolio funkcijos vykdymo logikos skirtumus

Norint efektyviai išspręsti šią problemą, prasminga suprasti, kaip susidaro metmenys (keliems matmenims). Tiesą sakant, tvarka paprasta – pirmiausia X, paskui Y ir paskutinis Z.

šerdis paleidžiama su 64×16 blokais, siūlai skirstomi į metmenis X, Y, Z tvarka – t.y. pirmieji 64 elementai suskaidomi į du metmenis, tada antrasis ir t.t.

Branduolys prasideda 16x64 blokais. Pirmasis ir antrasis 16 elementų pridedami prie pirmojo metimo, trečiasis ir ketvirtasis elementai pridedami prie antrojo metmenų ir t.t.

Kaip sumažinti skirtumus (atminkite - šakojimasis ne visada yra kritinio našumo praradimo priežastis)

  • kai gretimos gijos turi skirtingus vykdymo kelius – daug sąlygų ir perėjimų jose – ieškokite būdų, kaip pertvarkyti
  • ieškoti nesubalansuotos gijų apkrovos ir ryžtingai ją pašalinti (tai kai turime ne tik sąlygas, bet dėl ​​šių sąlygų pirmas siūlas visada kažką apskaičiuoja, o penktas nepatenka į tokią būseną ir yra neveikiantis)

Kaip maksimaliai išnaudoti GPU išteklius

GPU ištekliai, deja, taip pat turi savo apribojimų. Ir, griežtai tariant, prieš paleidžiant branduolio funkciją, prasminga apibrėžti ribas ir atsižvelgti į šias ribas paskirstant apkrovą. Kodėl tai svarbu?

Vaizdo plokštės turi apribojimus bendram gijų, kurias gali vykdyti vienas daugiaprocesorius, skaičius, maksimalus gijų skaičius viename bloke, didžiausias vieno procesoriaus deformacijų skaičius, skirtingų tipų atminties apribojimai ir kt. Visos šios informacijos galima prašyti programiškai, per atitinkamą API, ir anksčiau naudojant SDK komunalines paslaugas. (DeviceQuery moduliai NVidia įrenginiams, CLIinfo moduliai AMD vaizdo plokštėms).

Bendroji praktika:

  • gijų blokų/darbo grupių skaičius turi būti srauto procesorių skaičiaus kartotinis
  • bloko / darbo grupės dydis turi būti metmenų dydžio kartotinis

Tuo pačiu metu reikia nepamiršti, kad absoliutus minimumas - kiekviename procesoriuje vienu metu sukasi 3–4 metmenys / kelio frontai, išmintingi vadovai pataria vadovautis svarstymu - mažiausiai septyniais kelio frontais. Tuo pačiu – nepamirškite lygintuvui taikomų apribojimų!

Visas šias smulkmenas laikyti savo galvoje greitai pasidaro nuobodu, todėl skaičiuojant gpu užimtumą NVidia pasiūlė netikėtą įrankį - makrokomandų kupiną Excel (!) skaičiuotuvą. Čia galite įvesti informaciją apie maksimalų SM gijų skaičių, registrų skaičių ir bendrinamos (bendros) atminties dydį. srauto procesorius, ir naudojami parametrai funkcijoms paleisti – ir tai duoda procentą nuo resursų panaudojimo efektyvumo (ir tu plėšai plaukus suprasdamas, kad neturi pakankamai registrų, kad galėtum panaudoti visus branduolius).

naudojimo informacija:
http://docs.nvidia.com/cuda/cuda-c-best-practices-guide/#calculating-occupancy

GPU ir atminties operacijos

Vaizdo plokštės yra optimizuotos 128 bitų atminties operacijoms. Tie. idealiu atveju kiekviena atminties manipuliacija, idealiu atveju, vienu metu turėtų pakeisti 4 keturių baitų reikšmes. Pagrindinis programuotojo nepatogumas yra tai, kad šiuolaikiniai GPU kompiliatoriai nesugeba optimizuoti tokių dalykų. Tai turi būti padaryta tiesiai funkcijos kode ir vidutiniškai atneša našumo padidėjimo procentinę dalį. Atminties užklausų dažnis turi daug didesnį poveikį našumui.

Problema tokia – kiekviena užklausa atsakydama grąžina 128 bitų kartotinį duomenų. Ir kiekviena gija naudoja tik ketvirtadalį jo (įprasto keturių baitų kintamojo atveju). Kai gretimos gijos vienu metu dirba su duomenimis, esančiais nuosekliai atminties ląstelėse, tai sumažina bendrą atminties prieigos skaičių. Šis reiškinys vadinamas kombinuotomis skaitymo ir rašymo operacijomis ( sujungta prieiga – gerai! ir skaityti, ir rašyti) - ir teisingai sutvarkius kodą ( greita prieiga prie gretimos atminties dalies – blogai!) gali žymiai pagerinti našumą. Organizuojant branduolį – atsiminkite – gretimą prieigą – vienos atminties eilutės elementuose, darbas su stulpelio elementais nebėra toks efektyvus. Norite daugiau informacijos? Man patiko šis pdf arba google " atminties sujungimo būdai “.

Pirmaujančią poziciją nominacijoje „butelio kaklelis“ užima dar viena atminties operacija - nukopijuokite duomenis iš pagrindinio kompiuterio atminties į GPU . Kopijuojama ne bet kaip, o iš specialiai vairuotojo ir sistemos skirtos atminties srities: kai pateikiama užklausa nukopijuoti duomenis, sistema pirmiausia nukopijuoja šiuos duomenis ten, o tik tada įkelia į GPU. Duomenų perdavimo greitį riboja pralaidumas PCI magistralė Express xN (kur N yra duomenų linijų skaičius), per kurią šiuolaikinės vaizdo plokštės bendrauja su pagrindiniu kompiuteriu.

Tačiau papildomas lėtos atminties kopijavimas pagrindiniame kompiuteryje kartais yra nepateisinamos išlaidos. Išeitis – pasinaudoti vadinamuoju prisegta atmintis - specialiai pažymėta atminties sritis, kad operacinė sistema negalėtų su ja atlikti jokių operacijų (pavyzdžiui, iškrauti keisti / perkelti savo nuožiūra ir pan.). Duomenų perdavimas iš pagrindinio kompiuterio į vaizdo plokštę vykdomas nedalyvaujant operacinei sistemai - asinchroniškai, per DMA (tiesioginė prieiga prie atminties).

Ir galiausiai, šiek tiek daugiau apie atmintį. Bendra kelių procesorių atmintis paprastai yra suskirstyta į atminties bankus, kuriuose yra 32 bitų žodžiai - duomenys. Bankų skaičius tradiciškai skiriasi nuo vienos GPU kartos iki kitos – 16/32 Jei kiekviena gija prašo duomenų iš atskiro banko, viskas gerai. Priešingu atveju gaunamos kelios skaitymo / rašymo užklausos vienam bankui ir gauname konfliktą ( bendros atminties banko konfliktas). Tokie prieštaringi skambučiai yra nuoseklūs, todėl vykdomi nuosekliai, o ne lygiagrečiai. Jei visos gijos pasiekia tą patį banką, naudojamas „transliavimo“ atsakymas ( transliacija) ir nėra jokio konflikto. Yra keletas būdų, kaip efektyviai spręsti prieigos konfliktus, man tai patiko pagrindinių būdų, kaip atsikratyti prieigos prie atminties bankų konfliktų, aprašymas – .

Kaip dar greičiau atlikti matematinius veiksmus? Prisiminti, kad:

  • dvigubo tikslumo skaičiavimai yra didelė apkrova naudojant fp64 >> fp32
  • 3.13 formos konstantos kode pagal numatytuosius nustatymus interpretuojamos kaip fp64, jei aiškiai nenurodote 3.14f
  • norint optimizuoti matematiką, nebus nereikalinga konsultuotis su vadovais - ir ar yra kompiliatoriaus vėliavėlių
  • pardavėjai į savo SDK įtraukia funkcijas, kurios naudojasi įrenginio funkcijomis, kad pasiektų našumą (dažnai perkeliamumo sąskaita)

CUDA kūrėjams prasminga daug dėmesio skirti koncepcijai Kudos upelis, kurios leidžia vienu metu paleisti kelias pagrindines funkcijas viename įrenginyje arba derinti asinchroninį duomenų kopijavimą iš pagrindinio kompiuterio į įrenginį funkcijų vykdymo metu. „OpenCL“ tokios funkcijos dar nesuteikia 🙁

Profiliavimo šlamštas:

NVifia Visual Profiler yra įdomi programa, kuri analizuoja ir CUDA, ir OpenCL branduolius.

P.S. Kaip ilgesnį optimizavimo vadovą galiu rekomenduoti paieškoti visokių dalykų geriausios praktikos vadovas OpenCL ir CUDA.

  • ,

Kalbant apie lygiagretųjį skaičiavimą GPU, turime prisiminti, kokiu laiku gyvename, šiandien yra laikas, kai viskas pasaulyje taip įsibėgėja, kad prarandame laiko nuovoką, nepastebėdami, kaip jis skuba. Viskas, ką darome, yra susiję su dideliu informacijos apdorojimo tikslumu ir greičiu, tokiomis sąlygomis mums tikrai reikia įrankių, kad galėtume apdoroti visą turimą informaciją ir paversti ją duomenimis, be to, kalbant apie tokias užduotis, reikia atsiminti, kad šios užduotys būtinos ne tik didelėms organizacijoms ar megakorporacijoms, bet dabar tokias problemas turi spręsti ir paprasti vartotojai, kurie savo gyvybiškai svarbias užduotis, susijusias su aukštosiomis technologijomis, sprendžia namuose asmeninius kompiuterius! NVIDIA CUDA atsiradimas nenustebino, o labiau pateisino, nes kai tik reikės atlikti daug daugiau laiko reikalaujančių užduočių kompiuteryje nei anksčiau. Darbas, kuris anksčiau užtruko labai ilgai, dabar užtruks atitinkamai kelias minutes, tai turės įtakos bendram viso pasaulio paveikslui!

Kas yra GPU kompiuterija

GPU skaičiavimas yra GPU naudojimas techninėms, mokslinėms ir kasdienėms užduotims apskaičiuoti. Skaičiavimas naudojant GPU apima procesoriaus ir GPU naudojimą su nevienalyčiu pasirinkimu tarp jų, būtent: nuoseklią programų dalį perima CPU, o daug laiko reikalaujančias skaičiavimo užduotis atlieka GPU. Dėl to užduotys yra lygiagrečios, o tai lemia greitesnį informacijos apdorojimą ir sutrumpina darbo atlikimo laiką, sistema tampa produktyvesnė ir vienu metu gali apdoroti daugiau užduočių nei anksčiau. Tačiau norint pasiekti tokią sėkmę vien techninės įrangos palaikymo neužtenka, tokiu atveju reikalingas ir programinis palaikymas, kad aplikacija galėtų perkelti daugiausiai laiko reikalaujančius skaičiavimus į GPU.

Kas yra CUDA

CUDA yra technologija, skirta programuoti algoritmus supaprastinta C kalba, kuri veikia aštuntos kartos ir senesnių GeForce greitintuvų grafikos procesoriuose, taip pat atitinkamose NVIDIA Quadro ir Tesla kortelėse. CUDA leidžia į C programos tekstą įtraukti specialias funkcijas. Šios funkcijos parašytos supaprastinta C programavimo kalba ir veikia GPU. Pirminis CUDA SDK leidimas buvo išleistas 2007 m. vasario 15 d. Kad kodas būtų sėkmingas šia kalba, CUDA SDK turi savo C kompiliatorių komandinė eilutė nvcc iš NVIDIA. nvcc kompiliatorius yra pagrįstas atidaryti kompiliatorių Open64 ir yra skirtas versti pagrindinio kompiuterio kodą (pagrindinį, valdymo kodą) ir įrenginio kodą (aparatinės įrangos kodą) (failus su plėtiniu .cu) į objektų failus, tinkamus kurti galutinę programą arba biblioteką bet kurioje programavimo aplinkoje, pvz. , Microsoft Visual studijoje.

Technologijų galimybės

  1. C standartinė kalba, skirta lygiagrečiam GPU programų kūrimui.
  2. Paruoštos skaitmeninės analizės bibliotekos greitajai Furjė transformacijai ir pagrindinis tiesinės algebros programų paketas.
  3. Speciali CUDA tvarkyklė, skirta kompiuteriams su greitu duomenų perdavimu tarp GPU ir procesoriaus.
  4. Galimybė CUDA tvarkyklei sąveikauti su OpenGL ir DirectX grafikos tvarkyklėmis.
  5. Operacinės palaikymas Linux sistemos 32/64 bitų, Windows XP 32/64 bitų ir MacOS.

Technologijų privalumai

  1. CUDA taikomųjų programų programavimo sąsaja (CUDA API) yra pagrįsta standartine C programavimo kalba su tam tikrais apribojimais. Tai supaprastina ir palengvina CUDA architektūros mokymosi procesą.
  2. 16 KB bendroji atmintis tarp gijų gali būti naudojama vartotojo organizuotai talpyklai, kurios pralaidumas yra didesnis nei gaunant iš įprastų tekstūrų.
  3. Efektyvesnės operacijos tarp procesoriaus atminties ir vaizdo atminties.
  4. Visiškas aparatinės įrangos palaikymas sveikiesiems skaičiams ir bitinėms operacijoms.

Technologijos taikymo pavyzdys

cRark

Sunkiausia šios programos dalis yra tinktūra. Programa turi konsolės sąsają, tačiau dėl instrukcijų, pateiktų su pačia programa, ją galima naudoti. Toliau nurodyta trumpa instrukcija programos nustatymui. Išbandysime programos veikimą ir palyginsime su kita panašia programa, kuri nenaudoja NVIDIA CUDA, šiuo atveju gerai žinoma programa „Advanced Archive Password Recovery“.

Iš atsisiųsto cRark archyvo mums reikia tik trijų failų: crark.exe , crark-hp.exe ir password.def . Сrark.exe yra RAR 3.0 slaptažodžių laužtuvas be užšifruotų failų archyvo viduje (t.y. atidarę archyvą matome vardus, bet negalime išpakuoti archyvo be slaptažodžio).

Сrark-hp.exe yra komandinės eilutės RAR 3.0 slaptažodžių nulaužimo programa, kuri užšifruoja visą archyvą (t.y. atidarydami archyvą nematome nei pavadinimo, nei pačių archyvų ir negalime išpakuoti archyvo be slaptažodžio).

Password.def yra bet koks pervardytas tekstinis failas, kuriame yra labai mažai turinio (pvz.: 1 eilutė: ## 2 eilutė: ?* , tokiu atveju slaptažodis bus nulaužtas naudojant visus simbolius). Password.def yra cRark programos vadovas. Faile yra slaptažodžio atidarymo taisyklės (arba simbolių sritis, kurią crark.exe naudos savo darbe). Daugiau informacijos apie šių simbolių pasirinkimo parinktis parašyta tekstiniame faile, gautame atidarius iš „cRark“ programos autoriaus svetainės atsisiųstą: russian.def .

Treniruotės

Turiu iš karto pasakyti, kad programa veikia tik tuo atveju, jei jūsų vaizdo plokštė yra pagrįsta GPU, palaikančiu CUDA 1.1 pagreičio lygį. Taigi vaizdo plokščių serija, pagrįsta G80 lustu, pvz., GeForce 8800 GTX, negali būti svarstoma, nes jos turi aparatinės įrangos palaikymą CUDA 1.0 pagreitinimui. Naudodama CUDA, programa parenka tik 3.0 ir naujesnių versijų RAR archyvų slaptažodžius. Reikia įdiegti visą su CUDA susijusią programinę įrangą, būtent:

Kuriame bet kurį aplanką bet kur (pavyzdžiui, C: diske) ir vadiname bet kokiu pavadinimu, pavyzdžiui, „3.2“. Ten patalpinome failus: crark.exe , crark-hp.exe ir password.def bei slaptažodžiu apsaugotą / užšifruotą RAR archyvą.

Tada turėtumėte paleisti „Windows“ komandų eilutės konsolę ir eiti į joje sukurtą aplanką. Jei naudojate „Windows Vista“ ir „7“, turite iškviesti meniu „Pradėti“ ir paieškos laukelyje įvesti „cmd.exe“, „Windows XP“ meniu „Pradėti“ pirmiausia iškviesti dialogo langą „Vykdyti“ ir įvesti cmd.exe. “ joje. Atidarę konsolę įveskite tokią komandą kaip: cd C:\folder\ , šiuo atveju cd C:\3.2.

Įdarbinimas teksto redaktorius dvi eilutės (taip pat galite išsaugoti tekstą kaip .bat failą aplanke su cRark), kad atspėtų slaptažodžiu apsaugoto RAR archyvo su nešifruotais failais slaptažodį:

išjungti aidą;
cmd /K crark (archyvo pavadinimas).rar

Norėdami atspėti slaptažodžiu apsaugoto ir užšifruoto RAR archyvo slaptažodį:

išjungti aidą;
cmd /K crark-hp (archyvo pavadinimas).rar

Nukopijuokite 2 eilutes tekstinis failasį konsolę ir paspauskite Enter (arba paleiskite .bat failą).

rezultatus

Iššifravimo procesas parodytas paveikslėlyje:

CRark pasirinkimo greitis naudojant CUDA buvo 1625 slaptažodžiai per sekundę. Per vieną minutę, trisdešimt šešias sekundes, buvo atspėtas slaptažodis iš 3 simbolių: „q)$“. Palyginimui, mano dviejų branduolių „Athlon 3000+“ procesoriaus „Advanced Archive Password Recovery“ brutali jėga yra daugiausia 50 slaptažodžių per sekundę, o šiurkšti jėga užtruktų 5 valandas. Tai reiškia, kad RAR archyvo pasirinkimas naudojant bruteforce „cRark“ naudojant GeForce 9800 GTX+ vaizdo plokštę yra 30 kartų greitesnis nei naudojant centrinį procesorių.

Tiems, kurie turi Intel procesorių, gerą pagrindinę plokštę su aukštu sistemos magistralės dažniu (FSB 1600 MHz), procesoriaus sparta ir brutali jėga bus didesni. O jei turite keturių branduolių procesorių ir porą GeForce 280 GTX lygio vaizdo plokščių, slaptažodžio brutalios jėgos veikimas kartais paspartėja. Apibendrinant pavyzdį, reikia pasakyti, kad ši problema buvo išspręsta naudojant CUDA technologiją vos per 2 minutes, o ne per 5 valandas, o tai rodo didelį šios technologijos potencialą!

išvadas

Atsižvelgdami į šiandienos lygiagretaus skaičiavimo CUDA technologiją, aiškiai matėme visą šios technologijos galią ir didžiulį potencialą, naudojant slaptažodžio atkūrimo programos pavyzdį. RAR archyvai. Turiu pasakyti apie šios technologijos perspektyvas, ši technologija tikrai ras vietą kiekvieno ja pasinaudoti nusprendusio žmogaus gyvenime, nesvarbu, ar tai būtų mokslinės užduotys, ar su vaizdo apdorojimu susijusios užduotys, ar net ekonominės užduotys, reikalaujančios greito tikslaus skaičiavimo, visa tai lems neišvengiamą darbo jėgos padidėjimą produktyvumas, kurio negalima ignoruoti. Iki šiol frazė „namų superkompiuteris“ jau pradeda patekti į leksiką; Visiškai akivaizdu, kad norint tokį objektą paversti realybe, kiekvienuose namuose jau yra įrankis, vadinamas CUDA. Nuo kortelių, pagrįstų G80 lustu, išleidimo (2006 m.), puiki suma NVIDIA pagrindu veikiantys greitintuvai, palaikantys CUDA technologiją, kuri gali paversti svajonę apie superkompiuterius kiekvienuose namuose realybe. Skatindama CUDA technologiją, NVIDIA padidina savo patikimumą klientų akyse suteikdama papildomų funkcijų jų įrangai, kurią daugelis jau įsigijo. Belieka tikėti, kad netrukus CUDA vystysis labai greitai ir leis vartotojams visapusiškai išnaudoti visas lygiagretaus skaičiavimo galimybes GPU.