2.3.1. Memóriahasználat
Egy dupla-pontosságú lebeg®pontos szám tárolásához 8 byte memória szükséges.1 A 2.2. táblázat az ABS algoritmus memóriaigényét mutatja a független változók számának függvényében. (Az eredeti és a módosított Huang módszer között memó-riahasználat tekintetében nincs különbség.)
A Huang módszer megvalósításához az alábbi vektoroknak illetve mátrixoknak kell helyet biztosítani a memóriában: a, s, p, ha ∈ Rn vektorok és H ∈ Rn×n mátrix a részeredmények tárolásához szükséges, A ∈ Rm×n mátrix és b, x ∈ Rn vektorok a kiinduló adatokat illetve ez eredményt tárolják. Feltéve, hogy az együtthatómátrix négyzetes (m=n), az algoritmus futtatásához2·n2·8 + 6·n·8byte memóriára van szükség. Nagyobb együtthatómátrix esetén ez nehézségeket okozhat, hiszen a GPU memóriája véges. A fejlesztés során használt kártya 1.4 Gb memóriával rendelkezik,
1A dupla-pontosságú lebeg®pontos számok ábrázolásának szabályait az IEEE 754 szabvány írja el®.
n Memória igény
2.2. táblázat. Memóriahasználat a változók számának függvényében.
de ennek egy részét elfoglalja az operációs rendszer a monitorokon megjelen® kép tárolásához. A vektorok tárolásához használt memória eltörpülAésH mátrixok me-móriaigénye mellett. A legtöbb nVidia kártya nem csak a saját memóriájába másolt adatokkal képes számolni, hanem eléri a CPU memóriáját is. A CPU memória elérése nagyságrendekkel lassabb, mint a GPU memóriáé, ezért ezt a szükségmegoldást csak abban az esetben érdemes bevetni, ha a változók nem férnek el a GPU memóriában.
A GPU-ra tervezett algoritmus esetén a 8091 változós esetben az együttható mát-rix már a CPU memóriájában maradt. Azért az együtthatómátmát-rix marad a lassan elérhet® CPU memóriában, mert ennek minden sorához csak egyszer kell hozzáférni a futtatás során, így végeredményben itt a legkisebb a veszteség. (A CPU memória használatából adódó teljesítménycsökkenésr®l a kés®bbiekben lesz szó.)
Az ABS Huang alosztályának egyik fontos elméleti tulajdonsága, hogy Hi pro-jekciós mátrixok szimmetrikusak, így tárolásukhoz nem szükséges 8·n2 bájt (n a Hi négyzetes mátrix dimenziója). A szimmetricitás kihasználásával a memóriaigény csökkenthet® lenne kismérték¶ sebességromlás árán.
2.3.2. Mátrix m¶veletek GPU-n
Két mátrix összeszorzása GPU-n els® ránézésre nem t¶nik bonyolult feladatnak. Te-kintsük azR =AB feladatot példaként, ahol minden mátrixn-ed rend¶ és négyzetes.
A végrehajtandó m¶veletsor els® megközelítésben a következ®:
1. A kiinduló adatok a CPU memóriájában foglalnak helyet.
2. Lefoglaljuk az A, B és R mátrixok tárolásához szükséges területet a GPU me-móriájában.
3. A ésB mátrixokat felmásoljuk a CPU memóriájából a GPU memóriájába.
4. Futtatjuk a mátrixszorzásra írt kernelt n · n szálon, egy blokkban. Minden kernel-példányR mátrix egyetlen elemének kiszámításáért felel. Az, hogy me-lyik elemet számolja ki, illetve az eredményt hol tárolja, a szálblokkban elfoglalt helyét®l függ.
5. Az eredményül kapott R mátrixot lemásoljuk a GPU memóriájából a CPU memóriájába további feldolgozás vagy megjelenítés végett.
6. Ha a GPU memóriájában tárolt mátrixokra már nincs szükség a további szá-mításoknál, felszabadítjuk a lefoglalt GPU memóriát.
Ez a megközelítés nem optimális, hiszen minden szál a globális GPU memóriából ol-vas, és ide írja az eredményt is. Ebb®l adódóan a memóriára történ® várakozás a sz¶k keresztmetszet, így számítóegységek kapacitását nem tudjuk kihasználni. Gyorsabb végrehajtás érhet® el, ha a mátrixok al-mátrixait az osztott memóriába másoljuk, és a szorzást részenként végezzük el. Az al-mátrixok másolására fordított id® keve-sebb, mint a közös memóriahasználatnál a várakozásból adódó veszteség. A témával alaposabban a (Sanders/Kandort 2010) foglalkozik.
A fejleszt®k életét megkönnyítend® több nyílt forrású lineáris algebrát támogató kódkönyvtár létezik. A legismertebb talán a C nyelven írott BLAS (Basic Linear Algebra Subprograms)2. A BLAS CUDA architektúrára átültetett párhuzamos vál-tozata a cuBLAS. A különféle módon tárolt ritka mátrixokat is támogató cuSPARSE könyvtárral együtt szabadon felhasználható3.
2.3.3. Az adatforgalom csökkentése
Mint az el®z® pontból is látszik, a lineáris algebra és a mátrixm¶veletek területe jól körbejárt, mind a CPU, mind a GPU tekintetében. További teljesítménynövekedés úgy érhet® el, ha az elemi mátrix és vektorm¶veleteket összevonjuk annak érdekében, hogy a memória terhelését csökkentsük. A 2.3. táblázat bal oszlopa a módosított Hu-ang módszer lépéseit tartalmazza. A jobb oldali oszlop az egyes lépéseket megvalósító
2http://www.netlib.org/blas/
3https://developer.nvidia.com/cuda-toolkit
CUDA kernel nevét tartalmazza. Az ABS algoritmus futtatásához készített kerne-lek tipikusan több elemi m¶veletet vonnak össze, és felhasználják az el®z® pontban szerepl® optimalizálási lehet®ségeket.
Algoritmus lépései CUDA kernel név Ax=b (A∈Rm×n)
ipi pi VecSubVecMulConst (i) Hi =Hi−1− pTpi
ipi ·pTi MatSubMatDivConst ciklus vége
2.3. táblázat. A módosított Huang módszert megvalósító C függvények.
MakeEye Egységmátrixot hoz létre a GPU memóriájában. A bemutatott implementáció oszlopfolytonosan tárolja a mátrixok elemeit a memóriában.
MatMulColvec Összeszoroz egy mátrixot egy oszlopvektorral. (A memóriában a sor és az oszlopvektorok ábrázolása közt nincs különbség. Mindkét esetben egyszer¶en felsorolásra kerülnek a dupla-pontosságú formában ábrázolt elemek. Az elneve-zés csak a könnyebb megértést szolgálja.)
VecIsLessThen Megvizsgálja, hogy egy vektor összes elemének abszolút értéke egy határér-ték alá esik-e. Az algoritmus (b) lépése megvizsgálja, hogy az aix−bi vektor
nullvektor-e. A számábrázolási hibák terjedéséb®l adódóan ez az érték magasabb dimenziókban nem nulla lesz, hanem egy nagyon kicsi szám.
VecIsNull Egy vektorról eldönti, hogy nullvektor-e.
VecSubVecMulConst Egy vektort megszoroz egy konstanssal, majd két vektor különbségét képezi.
MatSubMatDivConst Egy mátrixot eloszt egy konstanssal, majd a két mátrix különbségét képezi.