SIMD intrinsics nisu tako zastrašujući, ali trebamo li ih koristiti?

Je li programiranje na niskoj razini grijeh ili vrlina? Ovisi.

Kada bih programirao za upotrebu vektorske obrade na modernom procesoru, idealno bi bilo da napišem neki kôd na svom omiljenom jeziku i on bi se pokrenuo što je brže moguće „auto-magično“.

Ako niste tek započeli s programiranjem prošlog tjedna, pretpostavljam da znate da svijet ne funkcionira tako. Vrhunska izvedba dolazi samo uz trud. Otuda i moje pitanje: koliko nisko trebamo ići?

Definirane su vektorske operacije

"Vektorska" operacija je matematička operacija koja obavlja više od jedne operacije. Vektorski zbrajanje može dodati osam parova brojeva umjesto redovnog zbrajanja, koji dodaje samo jedan par brojeva. Razmislite o tome da zamolite računalo da zbroji dva broja. To možemo učiniti redovitim uputama za dodavanje. Razmislite o tome da zamolite računalo da međusobno doda osam parova brojeva (izračunajte C1 = A1 + B1, C2 = A2 + B2, ... C8 = A8 + B8). To možemo učiniti s naredbom za dodavanje vektora .

Vektorske upute uključuju zbrajanje, oduzimanje, množenje i druge operacije.

 SIMD: paralelizam vektora

Računalni znanstvenici imaju otmjeno ime za vektorske upute: SIMD ili "Single Instruction Multiple Data". Ako o redovnoj naredbi za dodavanje razmišljamo kao o SISD (Single Instruction Single Data) gdje single znači jedan par unosa podataka, tada je vektorski add SIMD u kojem višestruko može značiti osam parova unosa podataka.

SIMD volim nazivati ​​"drugim hardverskim paralelizmom", jer se o "paralelnosti" u računalima toliko često misli da dolazi iz više jezgri. Broj jezgri se stalno povećavao. Uobičajeno je brojanje četiri jezgre, 20 ili više uobičajeno je u procesorima za poslužitelje, a Intelova najveća jezgra danas broji 72 jezgre u jednom Intel® Xeon Phi ™ procesoru.

Povećavaju se i veličine vektorskih uputa. Rane vektorske upute, poput SSE, istodobno su izvodile do četiri operacije. Intelova najveća vektorska širina danas, u AVX-512, istodobno izvodi do 16 operacija.

 Koliko nisko bismo trebali ići?

S toliko izvedbe koliko je uloga, koliko posla bismo trebali iskoristiti da bismo iskoristili ovu izvedbu?

 Odgovor je puno, a evo i zašto: Četiri jezgre mogu nam donijeti najviše 4 puta veću brzinu. AVX (upola manji od AVX-512, ali mnogo češći) može nam omogućiti najviše 8 puta veću brzinu. U kombinaciji mogu dobiti do 32X. Ako radite oboje, ima puno smisla.

Evo mog jednostavnog popisa kako pokušati iskoristiti vektorske upute (redoslijedom kojim bismo ih trebali pokušati primijeniti):

 1.     Prvo nazovite knjižnicu koja obavlja posao (krajnji u implicitnoj vektorizaciji). Primjer takve knjižnice je Intel® Math Kernel Library (Intel® MKL). Sav posao korištenja vektorskih uputa obavio je netko drugi. Ograničenja su očita: moramo pronaći knjižnicu koja radi ono što trebamo.

2.     Drugo, koristite implicitnu vektorizaciju. Ostanite apstraktni i napišite ga sami koristeći predloške ili kompajlere koji će vam pomoći. Mnogi kompajleri imaju sklopke i opcije vektorizacije. Sastavljači su vjerojatno najnosiviji i najstabilniji put. Bilo je mnogo predložaka za vektorizaciju, ali niti jedan nije vidio dovoljno upotrebe tijekom vremena da bi postao jasan pobjednik (nedavni unos su Intel® SIMD predlošci rasporeda podataka [Intel® SDLT]).

3.     Treće, koristite eksplicitnu vektorizaciju. Ovo je postalo vrlo popularno posljednjih godina i pokušava riješiti problem zadržavanja apstraktnosti, ali prisiljavanje prevoditelja da koristi vektorske upute kad ih inače ne bi koristio. Podrška za SIMD u OpenMP-u je ovdje ključni primjer, gdje su zahtjevi za vektorizaciju za prevoditelj dani vrlo eksplicitno. Nestandardna proširenja postoje u mnogim kompajlerima, često u obliku opcija ili "pragmi". Ako krenete ovom rutom, OpenMP je pravi put ako ste na C, C ++ ili Fortran.

4.     Napokon, postanite niski i prljavi. Koristite SIMD osobine. To je poput asemblerskog jezika, ali napisano unutar vašeg C / C ++ programa. SIMD osobine zapravo izgledaju kao poziv funkcije, ali uglavnom proizvode jednu naredbu (vektorsku uputu za rad, poznatu i kao SIMD uputa).

SIMD svojstva nisu zla; međutim, oni su krajnje utočište. Prva tri izbora uvijek su održiva za budućnost kada rade. Međutim, kad prva tri ne udovolje našim potrebama, definitivno bismo trebali pokušati koristiti SIMD osobine.

 Ako želite početi koristiti SIMD intrinsics, imat ćete ozbiljnu nogu ako ste navikli na programiranje na asemblerskom jeziku. Uglavnom je to zato što ćete lakše čitati dokumentaciju koja objašnjava operacije, uključujući Intelov izvrsni mrežni "Intrinsics Guide". Ako ste potpuno novi u ovome, naletio sam na nedavni blog ("SSE: pazi na prazninu!") Koji ima nježnu ruku u uvođenju intrinsike. Također mi se sviđa "Drobljenje brojeva s AVX-om i AVX2."

 Ako knjižnica ili kompajler mogu učiniti ono što trebate, SIMD-ovi sadržaji nisu najbolji izbor. Međutim, oni imaju svoje mjesto i nije ih teško koristiti kad se naviknete na njih. Pokušajte. Prednosti izvedbe mogu biti nevjerojatne. Vidio sam SIMD-ove intrinzike koje pametni programeri koriste za kôd koji vjerojatno neće stvoriti nijedan kompajler.

Čak i ako isprobamo osobine SIMD-a i na kraju pustimo knjižnicu ili kompajler da odradi posao, ono što naučimo može biti neprocjenjivo u razumijevanju najbolje upotrebe knjižnice ili kompajlera za vektorizaciju. I to je možda najbolji razlog da isprobamo SIMD intrinsics sljedeći put kad nam zatreba nešto za korištenje vektorskih uputa.

Kliknite ovdje da biste preuzeli besplatno 30-dnevno probno razdoblje za Intel Parallel Studio XE