Programavimas

„SIMD Intrinsics“ nėra tokie baisūs, bet ar turėtume juos naudoti?

Ar žemo lygio programavimas yra nuodėmė ar dorybė? Priklauso.

Programuodamas naudoti vektorinį apdorojimą šiuolaikiniame procesoriuje, idealiu atveju parašyčiau kodą savo mėgstama kalba ir jis veiktų kuo greičiau „automatiškai“.

Nebent ką tik pradėjote programuoti praėjusią savaitę, įtariu, kad žinote, kad pasaulis veikia ne taip. Didžiausias našumas ateina tik su pastangomis. Taigi mano klausimas: kaip žemai turėtume eiti?

Apibrėžtos vektorinės operacijos

„Vektorinė“ operacija yra matematinė operacija, atliekanti daugiau nei vieną operaciją. Vektorinis pridėjimas gali pridėti aštuonias skaičių poras vietoj įprasto pridėjimo, kuris prideda tik vieną skaičių porą. Apsvarstykite galimybę paprašyti kompiuterio pridėti du skaičius kartu. Tai galime padaryti reguliariai pridėdami instrukcijas. Apsvarstykite galimybę paprašyti kompiuterio pridėti aštuonias skaičių poras (apskaičiuokite C1 = A1 + B1, C2 = A2 + B2,… C8 = A8 + B8). Tai galime padaryti naudodami a vektorius pridėti instrukciją.

Vektorinės instrukcijos apima susiejimą, atimimą, dauginimą ir kitas operacijas.

 SIMD: vektorių lygiagretumas

Kompiuterių mokslininkai turi išgalvotą vektorinių instrukcijų pavadinimą: SIMD arba „Single Instruction Multiple Data“. Jei galvojame apie įprastą pridėjimo instrukciją kaip apie SISD (Single Instruction Single Data), kur viengungis reiškia vieną duomenų įvesties porą, tada vektorinis pridėjimas yra SIMD, kur daugkartinis gali reikšti aštuonias duomenų įvesties poras.

Man patinka SIMD vadinti „kita aparatinės įrangos lygiagretumu“, nes „paralelizmas“ kompiuteriuose taip dažnai laikomas kilusiu iš kelių branduolių. Pagrindiniai skaičiai nuolat didėjo. Keturių pagrindinių branduolių skaičius yra įprastas, 20 ar daugiau yra įprasta serverių procesoriuose, o didžiausias „Intel“ branduolių skaičius šiandien yra 72 branduoliai viename „Intel® Xeon Phi ™“ procesoriuje.

Vektorių instrukcijų dydžiai taip pat padidėjo. Ankstyvosios vektorinės instrukcijos, tokios kaip SSE, vienu metu atliko iki keturių operacijų. Didžiausias „Intel“ vektoriaus plotis šiandien, naudojant AVX-512, vienu metu atlieka iki 16 operacijų.

 Kaip žemai turėtume eiti?

Kiek mums tenka dirbti, kad išnaudotume šį spektaklį?

Atsakymo yra daug ir štai kodėl: Keturi branduoliai gali mums pagreitinti daugiausia 4 kartus. AVX (perpus mažesnis nei AVX-512, bet daug labiau paplitęs) gali mus pagreitinti daugiausia 8 kartus. Kartu jie gali gauti iki 32 kartų. Tai daryti labai prasminga.

Štai mano paprastas sąrašas, kaip bandyti išnaudoti vektorines instrukcijas (tokia tvarka, kokią turėtume bandyti jas pritaikyti):

 1.     Pirmiausia paskambinkite bibliotekai, kuri atlieka šį darbą (galutinis implicitinis vektorizavimas). Tokios bibliotekos pavyzdys yra „Intel® Math Kernel Library“ („Intel® MKL“). Visą darbą, norint naudoti vektorines instrukcijas, atliko kažkas kitas. Apribojimai akivaizdūs: turime rasti biblioteką, kuri darytų tai, ko mums reikia.

2.     Antra, naudokite numanomą vektorizavimą. Būkite abstraktus ir patys parašykite, naudodami šablonus ar kompiliatorius. Daugelis kompiliatorių turi vektorizavimo jungiklius ir parinktis. Ko gero, kompiliatoriai yra pats nešiojamasis ir stabiliausias būdas. Buvo daugybė vektorizavimo šablonų, tačiau nė vienas jų laikui bėgant nebuvo pakankamai naudingas, kad būtų aiškus nugalėtojas (naujausias įrašas yra „Intel® SIMD Data Layout Templates“ [Intel® SDLT]).

3.     Trečia, naudokite aiškų vektorizavimą. Pastaraisiais metais tai labai išpopuliarėjo ir bando išspręsti problemą, kaip išlikti abstrakčiu, bet priversti kompiliatorių naudoti vektorines instrukcijas, kai jis kitaip jų nenaudotų. SIMD palaikymas „OpenMP“ yra pagrindinis pavyzdys, kur vektorizavimo užklausos kompiliatoriui pateikiamos labai aiškiai. Nestandartiniai plėtiniai egzistuoja daugelyje kompiliatorių, dažnai kaip parinktys arba „pragmos“. Jei eisite šiuo maršrutu, „OpenMP“ yra būdas eiti, jei esate C, C ++ ar Fortran.

4.     Galiausiai, žemai ir purvinai. Naudokitės SIMD vidinėmis savybėmis. Tai panašu į surinkimo kalbą, bet parašyta jūsų C / C ++ programoje. Iš tikrųjų SIMD iš esmės atrodo kaip funkcijos iškvietimas, tačiau paprastai sukuria vieną komandą (vektorinę operacijos instrukciją, dar vadinamą SIMD instrukcija).

SIMD esmė nėra blogis; tačiau jie yra paskutinė išeitis. Pirmieji trys pasirinkimai visada yra labiau prižiūrimi ateityje, kai jie dirba. Tačiau kai pirmieji trys neatitinka mūsų poreikių, būtinai turėtume pabandyti naudoti SIMD vidines savybes.

Jei norite pradėti naudoti SIMD vidines savybes, turėsite rimtą koją, jei esate įpratęs programuoti surinkimo kalbą. Dažniausiai taip yra todėl, kad jums bus lengviau skaityti dokumentus, paaiškinančius operacijas, įskaitant puikų „Intel“ internetinį „vidinį vadovą“. Jei jums tai dar ne viskas, aš perėjau į neseniai paskelbtą tinklaraštį („SSE: nepamirškite atotrūkio!“), Kuris švelniai vertina savo esmę. Man taip pat patinka „Skaičiuoti numerius su AVX ir AVX2“.

Jei biblioteka ar kompiliatorius gali padaryti tai, ko jums reikia, SIMD esmė nėra geriausias pasirinkimas. Tačiau jie turi savo vietą ir jais nesunku naudotis, kai prie jų pripranti. Išbandykite juos. Spektaklio nauda gali būti nuostabi. Mačiau, kaip sumanūs programuotojai naudoja SIMD išteklius kodui, kurio greičiausiai nepagamins joks kompiliatorius.

Net jei išbandysime SIMD esmę ir galų gale leisime bibliotekai ar kompiliatoriui atlikti darbą, tai, ko išmokome, gali būti neįkainojama, norint suprasti geriausią bibliotekos ar kompiliatoriaus panaudojimą vektorizavimui. Tai gali būti geriausia priežastis išbandyti SIMD esmę kitą kartą, kai mums reikės kažko naudoti vektorinėms instrukcijoms.

Spustelėkite čia norėdami atsisiųsti nemokamą 30 dienų „Intel Parallel Studio XE“ bandomąją versiją

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