Betekintés az NVIDIA Volta architektúra képességeibe

A vállalat csak a gépi tanulásra fókuszált az új lapkánál, ami érdekes dizájnt szült.

Hirdetés

Megújult compute blokk

A compute blokkok természetesen rendelkeznek egy utasítás pufferrel is, amit ezúttal L0 gyorsítótárként nevez az NVIDIA, és ezek a streaming multiprocesszor L1 gyorsítótárát egészítik ki. Ami viszont fontos változás, hogy módosult a GigaThread motor ütemezése. Az újítás itt a szálak teljesen független ütemezése, ami az NVIDIA architektúráinak egy régi problémájára reagál. Nevezetesen arról van szó, hogy a korábbi architektúrák, ezen belül is a Pascal warpja (vagy wave-je, kinek hogy tetszik) az összes szál között egy programszámlálót osztott meg, és tartozott még ehhez egy speciális maszk is, ami azt határozta meg, hogy a warpon belül melyik szál aktív az adott időben. Ez viszont egy feltételes végrehajtás során problémás, mert számos szálat a warpban inaktívvá tesz, ugyanis csak az egyik feltételre vonatkozó szálakat tudja párhuzamosan futtatni, tehát az összes szál nem futhat egyszerre, amíg az eredeti maszk visszaállításra nem kerül. A Volta esetében a warp minden szála független ütemezést használ, így lehetővé válik a komplex algoritmusok sokkal általánosabb leprogramozása, emiatt – többek között – nem szükséges mindenáron elkerülni a finomszemcsés szinkronizációt alkalmazó algoritmusokat.

Az új compute blokk
Az új compute blokk [+]

A compute blokkokra rátérve egy ilyen egységben egy feladatirányító (dispatch) és egy warp ütemező található, amelyek többféle futószalagot etetnek. Az NVIDIA ugyan még mindig használja itt a CUDA mag kifejezést, de ez egyre inkább értelmetlenné válik, mivel amíg korábban egy CUDA mag egy komplex feldolgozó volt egy integer és egy lebegőpontos végrehajtásra tervezett ALU-val, addig a Volta esetében ez teljesen megváltozott. Az új architektúrában az utasításszavak végrehajtása a nekik megfelelő futószalagon történik. Ha 64 bites lebegőpontos operációról, azaz FP64-ről van szó, akkor egy darab 8 utas, FP32 esetében már egy darab 16 utas, integer mellett egy darab szintén 16 utas, míg az új Tensor műveleteknél egy darab 128 utas tömb áll rendelkezésre. Utóbbi esetben fontos kiemelni, hogy ezek strukturálva vannak, vagyis egy 128 utas tömb gyakorlatilag két darab úgynevezett tensor magot jelent, amelyek 64-64 darab ALU-t használnak. Ezek a tensor magok egyébként speciálisan gépi tanuláshoz, ezen belül is mátrixaritmetikára tervezett, kevert pontosságú feldolgozók.

Az NVIDIA CUDA magoknak az FP32-es ALU-kat tartja, ami elég sarkított nézet, ha azt tekintjük, hogy korábban ez egyszerre jelentett lebegőpontos és integer ALU-kat. Ezek tehát már nem CUDA magok, de vélhetően az egyszerűbb magyarázat érdekében a korábban bevezetett elnevezéseket valamire rá kellett illeszteni. Az FP32 ALU-k egyébként IEEE754-2008-as szabványnak megfelelők, és támogatják a MAD (Multiply-Add), illetve az FMA (Fused Multiply-Add) instrukciókat. Ezek az ALU-k támogatják az FP16-os műveleteket is, méghozzá úgy, hogy egy FP32-es feldolgozó két darab, egymástól nem függő 16 bites lebegőpontos operációt hajthat végre. A compute blokkokon belül átalakult a load/store egységek bekötése is, így ezek mostantól az előző bekezdésben található tömbök részei, azaz mind a négy, alapvetően eltérő képességű tömbhöz két-két ilyen egység tartozik, és ugyanígy egy-egy speciális funkciókért felelő egység (SFU) is bekötésre került, amelyek a trigonometrikus és transzcendens utasításokat hajthatják végre. Utóbbi változásoknak az a magyarázata, hogy a feladatirányító egységek száma compute blokkonként a korábbi kettőről egyre csökkent, így logikus volt a független load/store és SFU futószalagokat a tényleges feldolgozótömbök részévé tenni, mivel így ezek vezérlése is egyszerűsödik. Nem mellesleg az interpolációt a Volta már manuálisan végzi, vagyis az SFU-kból ez a lehetőség kikerült.

A compute blokkokban fontos változás, hogy a Pascal dizájnjához képest felére csökkent a közös regiszterterület mérete, aminek kapacitása így 64 kB lett. Ennek az oka, hogy egy compute blokkban feleannyi integer és FP32 ALU található, mint a Pascal esetében, tehát csak ehhez igazodott az NVIDIA, vagyis arányaiban igazából nem történt változás. Módosult a helyi adatmegosztás is, mivel az új shader multiprocesszor a Pascalban alkalmazott opciónál kétszer több, 128 kB-os helyi adatmegosztással (Local Data Share) rendelkezik. Ugyanakkor ez szintén nem jelent arányaiban változást, mivel a compute blokkok száma is megduplázódott, így egy blokkra továbbra is 32 kB-nyi terület jut.

A GV100 a textúrázási képességek területén nem újít igazán. Az egyes streaming multiprocesszorok egy darab textúrázó blokkot tartalmaznak, amelyet négy compute blokk használ egyszerre. Lényeges különbség azonban a Pascal dizájnjához képest, hogy a textúrázó blokkokhoz ezúttal nem tartozik különálló, írható és olvasható L1 gyorsítótár, így erre a feladatra a helyi adatmegosztáshoz kialakított memória van befogva. Ennek a célja egyértelműen a tranzisztorokon való spórolás, mivel a rendszer előnyére egyáltalán nem válik, de túl nagy lett így is maga a lapka, tehát bizonyos területeken muszáj volt nagyobb kompromisszumokat kötni.

A cikk még nem ért véget, kérlek, lapozz!

Azóta történt

Előzmények