A trükkösen duplázó Ampere
Régóta vár már a piac az új VGA-generációra, és az NVIDIA a hónap elején jelentette be az új GeForce-ok érkezését, amelyek közül az RTX 3080 jelölésű modell elérhetővé is vált. Ez a fejlesztés nem a sorozat leggyorsabbika, de mondhatni még éppen megfizethető áron kínál nagy teljesítményt.
Hirdetés
Az alapokat tekintve az NVIDIA a Turing helyére az Ampere architektúrát dobta be, amely az említett VGA esetében a GA102 kódnevet viselő lapkában fog dolgozni. A fejlesztés a Samsung 8 nm-es node-ján készül, és 28,3 milliárd tranzisztorból épül fel, miközben a kiterjedése 628,4 mm². Látható, hogy nem kis GPU-ról van szó, de ha az elmúlt évek generációit nézzük, akkor ezt az NVIDIA-tól már megszokhattuk.
Az Ampere architektúra elsődlegesen a Turing kigyúrásának tekinthető. A streaming multiprocesszorok általános felépítése sok szempontból hasonló, de azért vannak trükkös változások is. Olyan dolgokhoz tér vissza az NVIDIA, amelyeket a G80 megjelenése, vagyis effektíve a 2006-os esztendő előtti időkben alkalmaztak, ráadásul ezekben a nagyon rég elfeledett ötletekben még van is ráció – de nézzük inkább a részleteket!
Az Ampere architektúra multiprocesszora [+]
Az Ampere multiprocesszorokon belül marad a jól megszokott, négy compute blokk. Ezekben található egy L0 utasítás gyorsítótár, egy feladatirányító (dispatch), illetve egy warp ütemező, amelyek többféle futószalagot etetnek. Az NVIDIA természetesen továbbra is használja a CUDA mag kifejezést, de ahogy korábban, úgy ennek az Ampere esetében sincs értelme, mivel már nem komplex feldolgozók találhatók a blokkokon belül. Ennek megfelelően az Ampere architektúrában – a Turinghoz hasonlóan – az utasításszavak végrehajtása a nekik megfelelő futószalagon történik. Ha 32 bites lebegőpontos operációról, azaz FP32-ről van szó, akkor egy darab 16 utas, 32 bites integer, azaz INT32 mellett egy darab szintén 16 utas, míg a Tensor műveleteknél egy darab 256 utas, structural sparsity támogatással dolgozó tömb áll rendelkezésre. Utóbbi esetben fontos kiemelni, hogy ezek strukturálva vannak, vagyis egy 256 utas tömb gyakorlatilag két darab úgynevezett tensor magot jelent, amelyek 128-128 darab ALU-t használnak.
A dizájn alapjai ismerősek lehetnek, de az NVIDIA bedobott egy trükköt, ugyanis amíg a 16 utas FP32 feldolgozótömb változatlan, addig az INT32-es opció kiegészült olyan formában, hogy már 32 bites lebegőpontos operációkat is képes végrehajtani. Az új rendszerben tehát egy compute blokkon belül akár két darab 16 utas FP32 feldolgozótömb is befogható, vagyis egyszerre két darab olyan warp (megszokott szóhasználattal élve wave) is futtatható, amelyekben 32 bites lebegőpontos operációk kerülnek végrehajtásra. Ezzel az NVIDIA ismét bevezeti a co-issue feldolgozási modellt, méghozzá 16+16-os formában, vagyis ideális körülmények fennállása esetén egy compute blokk 32 bites lebegőpontos számítási teljesítménye a Turinghoz képest megduplázódik. A kérdés az, hogy mi az ideális körülmény.
Elsődlegesen a két futtatott warp egy ütemezőn kerül kiosztásra, vagyis a feldolgozandó feladatok között nem állhat fenn függőség. Ez a legfontosabb kritérium. Ha az ütemező a compute blokkon belül nem tud kiosztani két olyan warpot, amelyek nem függnek egymástól, akkor csak az alapértelmezett FP32 feldolgozótömb fog működni. Szintén lényeges, hogy ne legyen INT32 feladat sem, ugyanis ebben az esetben muszáj lekötni az INT32 operációkat kezelő feldolgozótömböt, amely értelemszerűen így nem tud FP32-es operációkat elvégezni. Ezekben az esetekben az elméletileg beépített FP32-es számítási kapacitás fele érhető el.
Az NVIDIA egyébként továbbra is az FP32-es ALU-kat tartja CUDA magoknak, és ezek a részegységek megfelelnek az IEEE754-2008-as szabványnak, vagyis támogatják a MAD (Multiply-Add), illetve az FMA (Fused Multiply-Add) instrukciókat. Az FP16-os műveleteket az alapértelmezett feldolgozótömb kezeli, 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 másodlagos, INT32-es feldolgozótömb ugyan az FP32-t támogatja, de az FP16-ot már nem, tehát az Ampere esetében a szimpla és a felezett pontosság melletti elméleti számítási teljesítmény megegyezik, ellentétben a Turing dizájnjával, ahol utóbbi duplája volt az előbbinek. Itt megjegyzendő, hogy az új architektúra támogatja a bfloat16 adattípust is, ami a gépi tanulás tréning szakaszánál lehet hasznos. Ennek az az előnye, hogy a 32 bites lebegőpontos adattípussal megegyezően 8 bites exponenst használ, viszont a mantissza 23 bit helyett csak 7 bites. Ezzel természetesen a pontosság csökken, de a célterületet tekintve így is kedvezőbb a normál 16 bites lebegőpontos (FP16) adattípushoz viszonyítva.
A load/store egységek bekötése gyakorlatilag a Turing dizájnját másolja, ahogy a trigonometrikus és transzcendens utasítások végrehajtásáért felelős speciális funkciókat biztosító egység (SFU) kialakítása is. A textúrázási képességek területén sincs igazán újítás. Az egyes streaming multiprocesszorok egy darab, négy csatornát biztosító textúrázó blokkot tartalmaznak, amelyet négy compute blokk használ egyszerre.
A compute blokkokon belüli regiszterterület marad 64 kB, vagyis annyi, amennyi a Voltában és a Turingban volt. Ez abból a szempontból nem túl szerencsés, hogy az FP32 feldolgozók megduplázódtak a compute blokkon belül, miközben az adatokat annyi helyen kell tárolni, mint amennyit az előző két generáció architektúrája kínált. Ha esetleg olyan shadert fog futtatni a compute blokk, amelynek igen nagy a regiszternyomása, akkor nem biztos, hogy befogható a második 16 utas FP32 feldolgozótömb, vagyis egy fog működni. Az úgynevezett LDS-nyomás hasonlóan probléma lehet compute shaderek esetében, de ritkábban, mivel az Ampere-en belül az NVIDIA átalakította az L1 gyorsítótár működését. Egyrészt a sávszélességét megduplázták 64-ről 128 bájt/ciklusra, másrészt 96-ról 128 kB-ra nőtt a kapacitása. Utóbbi több konfigurációban fogható be. Amennyiben az adott compute blokk grafikai feladatot futtat, akkor kötelező 64 kB-ot biztosítani a textúrázóegységeknek, illetve az egyéb adatok tárolására, 48 kB lesz a helyi adatmegosztás, illetve 16 kB fenntartása szükséges a grafikai futószalagokhoz. Compute feladatok mellett már sokkal szabadabb a felhasználás, az általános gyorsítótár 28, 64, 96, 112, 120 vagy 128 kB lehet, az éppen aktuális maradék pedig felhasználható helyi adatmegosztásra.
Kétségtelen, hogy az új generáció multiprocesszorában található compute blokkok elég bonyolultan működnek ahhoz képest, amit mondjuk a Turing esetében megszokhattunk. A legnagyobb és egyben legfurcsább fejlesztés a 16+16 co-issue feldolgozási modell, amire azért állhatott át az NVIDIA, mert a Turing dizájnjában már eleve ott csücsült a 16 utas INT32 feldolgozótömb, és azt nem túl nagy tranzisztorköltség kiegészíteni FP32 operációk támogatásával. Még ha nem is tud mindig működni a feldolgozók egyik fele, akkor is megérhette, mert a tipikus teljesítményelőny, amit a gyakorlatban hoz, nagyobb lehet, mint amennyi tranzisztor beépítését igényelte. Erre természetesen lehet optimalizálni a programkódban is, sőt kifejezetten ajánlott, mert az Ampere teljesítménye a korábbi generációkhoz viszonyítva jobban függ majd a futtatott shaderektől.
A cikk még nem ért véget, kérlek, lapozz!