24. tétel - Optimalizálás a grafikus kártyán
Mik az optimális GPU kód jellemzői (szálak, elágazások, adat/számítás arány, occupancy)? Hogyan választható meg az optimális blokkméret? Atomi műveleteket hogyan lehet helyettesíteni?
Szálak
- A szálak blokkokba szerveződnek
- Az egy blokkon belül futtatható szálak száma korlátos (pl. 1024)
- tehát ennél több szálhoz több blokk kell
- A fizikai futtatás warponként történik
- warp: a blokkok felbontásra kerülnek 32 szálas részekre
- a multiprocesszorok folyamatosan figyelik, hogy melyik warp futtatható
- ha elakad egy warp, próbál másikra váltani → ha nem tud, akkor kihasználatlanul áll
- ezért fontos, hogy a szálak minél jobban párhuzamosítva legyenek (függetlenek legyenek)
- ha elakad egy warp, próbál másikra váltani → ha nem tud, akkor kihasználatlanul áll
Elágazások
- A GPU-n belül egy vezérlő tartozik a VE-khez → egyidőben csak ugyanazt az utasítást tudják végrehajtani
- SIMT végrehajtás → pl. míg bizonyos szálak az igaz ágat futtatják, a többi kikapcsol, majd fordítva
- mivel ez rosszabb teljesítményt okoz, törekedni kell a minél kevesebb elágazás használatára a kódban
Adat-számítás arány
- minden multiprocesszoron belül korlátozott mennyiségű memória van
- ha a warpok túl sok regisztert és memórát használnak, kevesebb warpot tud futtatni egyszerre a multiprocesszor
- fontos tehát csak a szükséges méretű memóriát használni, optimalizálni
Occupancy
- a warpok mérete 32 → célszerű 32-vel osztható blokkméretet választani
- pl. ha marad 16 szál, az ugyanúgy 1 warpot fog elfoglalni → rosszabb kihazsnáltság
- finoman szemcsézettség megfontolása:
- pl. annyi a feladat, hogy 1030 szál végezzen egymástól független számításokat
- ekkor jobb kihasználtság érhető el, ha 2db 515 szálas blokkot használunk, mintha 1db 1024 + 1db 6 szálasat használnánk
Atomi műveletek helyettesítése
- probléma: két szál akar egyszerre atomi műveletet végerehajtani ugyanazon a memóriacímen → szerializálni kell, ami lassítja a végrehajtást
- a cél a lehető legkevesebb atomi művelet használata (nem mindig kerülhető el)
- a helyettesítés történhet pl. redukcióval
- minimumkiválasztás: \(\frac{N}{2}\) szál összehsonlít → szinkronizál → \(\frac{N}{4}\) szál összehasonlít, stb.
- a végén megkapjuk a min. elemet
- shared memóriával gyorsíthatjuk tovább
- minimumkiválasztás: \(\frac{N}{2}\) szál összehsonlít → szinkronizál → \(\frac{N}{4}\) szál összehasonlít, stb.