Sziasztok!
LeĂrok pár gondolatot - mert nagyon bugyognak bennem - Ă©s hátha van valami jĂł ötletetek hozzájuk.
SzĂłval azon gondolkozok, hogy hogyan kĂ©ne a SIMD-s vektor utasĂtásokra Ă©s a GPUs nagyon mĂ©ly hierarchiájĂş párhuzamos vĂ©grehajtĂłkra jĂłl kĂłdot generálni, Ă©s nem akar összeállni a dolog (nyilván nem triviális).
Illetve az a rĂ©sz triviális, ha teljesen fĂĽggetlen feladatok vannak, amin ugyan azt a műveletsort kell vĂ©gigcsinálni, Ă©s a szálak között nincs adatfĂĽggĹ‘sĂ©g / kommunikáciĂł, akkor az triviálisan párhuzamosĂthatĂł (vagy szekvencializálhatĂł, ha visszafelĂ© kell menni). De a többi eset nagyon nehĂ©z.
Az egyik ötlet: hasonlĂt-e ez a dolog a regiszter allokáciĂłra? Pl. az ember azt mondhatja, hogy tegyĂĽk fel, hogy van vĂ©gtelen sok szálunk, Ă©s megprĂłbáljuk azokra szĂ©tosztani a feladatot (elĹ‘ször lebontjuk skalárokra), majd ezeket megprĂłbáljuk egymásmellĂ© gyűjteni, hogy vektorutasĂtások legyenek belĹ‘lĂĽk, illetve ha kevesebb szál van, mint ami kell, akkor vissza-szekvencializálunk. Működhet-e ez? (elvileg a Csaba által emlĂtett ISPC v mi, Inteles compiler hasonlĂłkat csinál messzirĹ‘l nĂ©zve, asszem).
Viszont az adatkommunikációknál és a többszintű esetben nem tudom mi van. A GPU-s tájkép alulról nézve a következő durván nézve:
- alul vannak a 128 bit-es SIMD regiszteres műveletek, ez kb. ua mint a CPU-kon.
- ezeken felül vannak a szálak 32 vagy 64-es csoportokban (warp NVIDIA-n, wavefront AMD-n, etc). Itt vannak olyan műveletek, amelyek a warp szálak között skalár regiszter méretű (32-64 bit) adatokat tudnak átvenni (shuffle szerű), ami nagyon gyors és hatékony. Időnként még a divergens esetek is kezelhetőek + van maszkolás, ha nem kell minden szál az adott művelethez. Ezekből úgy fest egyre több lesz.
- a warpok/szálak felett van a rendes "nagy" szálcsoport, ami kb. 256-1024 szálat tartalmaz, tehát jónéhány warpot ölel fel. Ez a legnagyobb egység, amin belül a szálak még szinkronizálhatóak az élettartamuk alatt, illetve van egy dedikált gyors memóriája (shared/local memory), ami néhány 10k byte méretű és csak ez a csoport látja.
- a szálcsoportok felett van a teljes számĂtási rács, ami ki lett kĂĽldve a kártyára, amelybĹ‘l azonban nem biztos h egyszerre mindegyik fut, Ăgy azok között nincs szinkronizáciĂł, csak a kernelhĂvás vĂ©ge, Ă©s csak a globális, lassĂş memĂłrián (VRAM)
keresztül kommunikálnak.
- aztán ugye lehet még több kártya is egy gépben, ahol az eszközök között gyorsabb lehet a kommunikáció, mint a RAM felé.
SzĂłval erre elĂ©g macerás átkĂ©pezni számĂtásokat, kĂ©rdĂ©s, hogy mit Ă©rdemes csinálni. NĂ©hány elkĂ©pzelĂ©s:
- mivel a fordĂtĂł mindig limitált lesz, a programozĂłnak kell tudnia expliciten leĂrnia ilyesmiket, viszont ha mindenhova át kell adogatni ilyen szálcsoportokkal kapcsolatos paramĂ©terket, az elcsĂşfĂtja a kĂłdokat (pl. ha user defined operátort akar az ember, akkor nem is "fĂ©r el" az ilyen info).
- node vannak ezek az implicit argumentumok, Ă©s lehetne ezt kicsit abuzálni, Ă©s lehetne absztraktul azt mondani, hogy egy adott fĂĽggvĂ©nyt a programozĂł megĂrhat nĂ©hány kĂĽlönbözĹ‘ granularitásban, pl. 4-32-256-os szálmĂ©rettel, Ă©s ezek közĂĽl választhat a fordĂtĂł, amikor oda jut, hogy na ezt az adott fĂĽggvĂ©nyt Ă©ppen milyen környezetbe kell beágyazni Ă©s ott valĂłjában mennyi szál van. Mert párhuzamos kĂłdbĂłl visszatĂ©rni szekvencializált kĂłdra valszeg könnyebb, mint fordĂtva. És ez a paramĂ©ter olyasmi lenne, ami fordĂtási idĹ‘ben eldĹ‘l, Ăgy az ehhez kapcsolĂłdĂł esetszĂ©tválasztás teljesen eltűnhet fordĂtáskor. CserĂ©be viszont lehet, hogy sok kĂłd duplikáciĂłval jár, amit nem akarok de mĂ©g nem látom át ez hogy nĂ©zne ki jobban.
- lehetne a szálcsoportosdinak egy absztrakt modellje, ahol alapvetően az absztrakt szálak között scatter, gather és shuffle műveletek vannak, meg szinkronizáció, meg ilyesmik, mert úgyfest az minden ilyen környezetben van nagyjából.
- nem tudom minek kĂ©ne elĹ‘bb eldöntĹ‘dnie: a párhuzamosĂtásnak, vagy a memĂłria layoutnak, valĂłszĂnűleg mindkĂ©t irányban kĂ©ne tudnia működni a megszorĂtásnak Ă©s alkalmazkodásnak, mert mindkettĹ‘re vannak use-casek.
Egy másik Ă©rdekes aspektus: mennyire lehet tudni, hogy honnan jön a párhuzamosĂtási lehetĹ‘sĂ©g? Nekem valahogy azaz intuĂciĂłm, hogy mindig abbĂłl indulunk ki, hogy valamibĹ‘l sok van, Ă©s azok ugyan azt akarjuk csinálni, Ă©s ennek magas szintrĹ‘l kĂ©ne látszĂłdnia, tehát felĂĽlrĹ‘l lefelĂ©.
Ugyanakkor meg az clang/llvm vektorizáciĂłjánál olvastam, hogy abban van olyan pass, ami nĂ©zegeti elĹ‘re hátra N utasĂtásig, hogy hol vannak összevonhatĂł skalár műveletek, amikbĹ‘l vektor műveletet lehet csinálni. Ez meg alulrĂłl felfelĂ© megy. Szerintetek ez is olyan, hogy mindkettĹ‘re szĂĽksĂ©g lehet, vagy a clangos csak kĂ©nyszermegoldás, mert nincs elĂ©g felĂĽlrĹ‘l jövĹ‘ informáciĂłja?
Egyelőre kb. itt tartok ezügyben...
ĂĽdv,
D.