Ordering MCMC gyorsítása OpenCL környezetben



Hasonló dokumentumok
Készítette: Trosztel Mátyás Konzulens: Hajós Gergely

Magas szintű optimalizálás

OpenCL - The open standard for parallel programming of heterogeneous systems

GPU alkalmazása az ALICE eseménygenerátorában

OpenCL alapú eszközök verifikációja és validációja a gyakorlatban

AliROOT szimulációk GPU alapokon

Párhuzamos programozási platformok

Java II. I A Java programozási nyelv alapelemei

Teszt Az nvidia GeForce VGA kártyák gyakorlati teljesítménye a Dirt3-ban

Szimuláció RICHARD M. KARP és AVI WIGDERSON. (Készítette: Domoszlai László)

Java II. I A Java programozási nyelv alapelemei

FIR SZŰRŐK TELJESÍTMÉNYÉNEK JAVÍTÁSA C/C++-BAN

Grafikus csővezeték 1 / 44

Feladat. Bemenő adatok. Bemenő adatfájlok elvárt formája. Berezvai Dániel 1. beadandó/4. feladat április 13. Például (bemenet/pelda.

KÖZELÍTŐ INFERENCIA II.

Párhuzamos és Grid rendszerek

5-6. ea Created by mrjrm & Pogácsa, frissítette: Félix

Programozási módszertan. Mohó algoritmusok

KÖZELÍTŐ INFERENCIA II.

Hardver Ismeretek IA32 -> IA64

Mintavételes szabályozás mikrovezérlő segítségével

Párhuzamos programozási platformok

Csoportos üzenetszórás optimalizálása klaszter rendszerekben

Gauss-Seidel iteráció

Újrakonfigurálható technológiák nagy teljesítményű alkalmazásai

SAT probléma kielégíthetőségének vizsgálata. masszív parallel. mesterséges neurális hálózat alkalmazásával

egy szisztolikus példa

Fordító részei. Fordító részei. Kód visszafejtés. Izsó Tamás szeptember 29. Izsó Tamás Fordító részei / 1

Számítógépek felépítése

SZÁMÍTÓGÉP ARCHITEKTÚRÁK

Hatékony memóriakezelési technikák. Smidla József Operációkutatási Laboratórium január 16.

Adatszerkezetek 2. Dr. Iványi Péter

Számítógépes döntéstámogatás. Genetikus algoritmusok

Digitális technika VIMIAA01 9. hét Fehér Béla BME MIT

Digitális technika VIMIAA01 9. hét

GPU Lab. 4. fejezet. Fordítók felépítése. Grafikus Processzorok Tudományos Célú Programozása. Berényi Dániel Nagy-Egri Máté Ferenc

FEGYVERNEKI SÁNDOR, Valószínűség-sZÁMÍTÁs És MATEMATIKAI

8. gyakorlat Pointerek, dinamikus memóriakezelés

Gauss elimináció, LU felbontás

Flynn féle osztályozás Single Isntruction Multiple Instruction Single Data SISD SIMD Multiple Data MISD MIMD

Függvények növekedési korlátainak jellemzése

Teljesítmény Mérés. Tóth Zsolt. Miskolci Egyetem. Tóth Zsolt (Miskolci Egyetem) Teljesítmény Mérés / 20

Dr. habil. Maróti György

Bevezetés a párhuzamos programozási koncepciókba

Vizuális adatelemzés - Gyakorlat. Budapesti Műszaki és Gazdaságtudományi Egyetem Méréstechnika és Információs Rendszerek Tanszék

Bánhelyi Balázs, Csendes Tibor, Palatinus Endre és Lévai. Szeptember 28-30, 2011, Balatonöszöd, Hungary

Processzor (CPU - Central Processing Unit)

Számítógépek felépítése, alapfogalmak

VLIW processzorok (Működési elvük, jellemzőik, előnyeik, hátrányaik, kereskedelmi rendszerek)

7. fejezet: Mutatók és tömbök

Programozási segédlet

Ismerkedjünk tovább a számítógéppel. Alaplap és a processzeor

Programozás II. előadás

Hatékonyság 1. előadás

Mesterséges Intelligencia MI

elektronikus adattárolást memóriacím

Nagyságrendek. Kiegészítő anyag az Algoritmuselmélet tárgyhoz. Friedl Katalin BME SZIT február 1.

GPU-Accelerated Collocation Pattern Discovery

Algoritmuselmélet. Katona Gyula Y. Számítástudományi és Információelméleti Tanszék Budapesti Műszaki és Gazdaságtudományi Egyetem. 13.

Bevezetés a programozásba. 5. Előadás: Tömbök

Exact inference in general Bayesian networks

Labor gyakorlat Mikrovezérlők

Analóg-digitális átalakítás. Rencz Márta/ Ress S. Elektronikus Eszközök Tanszék

Simon Balázs Dr. Goldschmidt Balázs Dr. Kondorosi Károly. BME, Irányítástechnika és Informatika Tanszék

Rőczei Gábor Szeged, Networkshop

C programozási nyelv Pointerek, tömbök, pointer aritmetika

Adatszerkezetek Tömb, sor, verem. Dr. Iványi Péter

Tartalom Keresés és rendezés. Vektoralgoritmusok. 1. fejezet. Keresés adatvektorban. A programozás alapjai I.

Számítógép felépítése

A fordítóprogramok szerkezete. Kódoptimalizálás. A kódoptimalizálás célja. A szintézis menete valójában. Kódoptimalizálási lépések osztályozása

Programozás I. 1. előadás: Algoritmusok alapjai. Sergyán Szabolcs

Programozás alapjai 9. előadás. Wagner György Általános Informatikai Tanszék

A félév során előkerülő témakörök

Keresés és rendezés. A programozás alapjai I. Hálózati Rendszerek és Szolgáltatások Tanszék Farkas Balázs, Fiala Péter, Vitéz András, Zsóka Zoltán

Matematikai alapok. Dr. Iványi Péter

Bánsághi Anna 2014 Bánsághi Anna 1 of 68

Multihalmaz, intervallumhalmaz

Orvosi készülékekben használható modern fejlesztési technológiák lehetőségeinek vizsgálata

Programozás alapjai. 10. előadás

Heterogén számítási rendszerek

Digitális jelfeldolgozás

Konjugált gradiens módszer

Összetett programozási tételek Rendezések Keresések PT egymásra építése. 10. előadás. Programozás-elmélet. Programozás-elmélet 10.

1. Alapfogalmak Algoritmus Számítási probléma Specifikáció Algoritmusok futási ideje

C++ programozási nyelv

Osztott algoritmusok

Digitális technika (VIMIAA02) Laboratórium 1

GPGPU-k és programozásuk Dezső, Sima Sándor, Szénási

Programozás I gyakorlat

Szoftvertechnológia alapjai Java előadások

Algoritmusok és adatszerkezetek gyakorlat 07

GPU Lab. 3. fejezet. Az X86 Utasításkészlet. Grafikus Processzorok Tudományos Célú Programozása. Berényi Dániel Nagy-Egri Máté Ferenc

Gépi tanulás a gyakorlatban. Lineáris regresszió

Digitális technika (VIMIAA02) Laboratórium 1

Google App Engine az Oktatásban 1.0. ügyvezető MattaKis Consulting

A verem (stack) A verem egy olyan struktúra, aminek a tetejéről kivehetünk egy (vagy sorban több) elemet. A verem felhasználása

Microsoft Excel Gyakoriság

Bevezetés a programozásba I 3. gyakorlat. PLanG: Programozási tételek. Programozási tételek Algoritmusok

4. Programozási nyelvek osztályozása. Amatőr és professzionális

Problémamegoldás kereséssel. Mesterséges intelligencia március 7.

Átírás:

Budapesti Műszaki és Gazdaságtudományi Egyetem Villamosmérnöki és Informatikai Kar Méréstechnika és Információs Rendszerek Tanszék Ordering MCMC gyorsítása OpenCL környezetben Önálló laboratórium 1 Készítette Trosztel Mátyás Konzulens Hajós Gergely 2012. május 29.

Tartalomjegyzék 1. Bevezetés 2 1.1. Az MCMC algoritmus................................. 2 1.2. Ordering MCMC algoritmus.............................. 2 1.3. Ordering score számítás................................ 2 1.4. Eddigi eredmények................................... 2 1.5. OpenCL......................................... 3 2. Tervezés és implementálás 3 2.1. Alapvető technikák................................... 3 2.2. Score számítás gyorsítása............................... 4 2.3. Score indexelés..................................... 5 2.4. Score cache mérete................................... 5 2.5. Szülői halmazok generálása.............................. 6 2.6. Ordering score számítás gyorsítása.......................... 7 2.7. Validálás......................................... 7 3. Eredmények 8 3.1. Futási eredmények................................... 8 3.2. További lépések..................................... 8 Köszönetnyilvánítás 9 Hivatkozások 10 1

1. Bevezetés 1.1. Az MCMC algoritmus Az MCMC (Markov Chain Monte Carlo) algoritmus során egy olyan megfelelően konstruált Markov-láncból mintavételezünk, amely stacionárius eloszlása a céleloszlás. Nagy számú szimulációs lépés esetén a minták a kívánt eloszlást követik. A mintavétel minősége a lépésszám növelésével javítható. Az algoritmus sztochasztikus tulajdonsága miatt több szimuláció eredményét érdemes összevetni a stabilabb adat eléréséért. 1.2. Ordering MCMC algoritmus Az Ordering MCMC a sorrendezések tere felett lépked. Ez a tér a struktúrák teréhez hasonlóan szuperexponenciális, de kevésbé tüskés, így jobb konvergenciát biztosít. Emellett a sorrendezéssel kompatibilis gráf DAG (irányított körmentes gráf) lesz, ami lehetővé teszi a valószínűségi változók szülői halmazainak egymástól független számítását. Ezt kihasználva az algoritmus párhuzamosítható. A keresési tér csökkentése érdekében maximalizálni szoktuk a szülői változók számát. Ez egy elfogadható közelítés, mert a legtöbb esetben nem áll rendelkezésünk elég adat a nagyobb szülői számmal járó feltételes valószínűségek számításához. 1.3. Ordering score számítás Az adatunk valószínűségét egy adott sorrendezésre nézve a következőképp számíthatjuk ki: P (D ) = G G k, score(x i, P a G (X i ) D), (1) i ahol score(x i, P a G (X i ) D) annak a valószínűsége, hogy D adat mellett X i valószínűségi változónak P a G (X i ) a szülői halmaza. G k a sorrendezéssel kompatibilis maximum k darab szülőt tartalmazó gráfok halmaza. P a G (X i ) az X i valószínűségi változó szülei a G gráfban. Mivel a szülői halmazok egymástól függetlenül számíthatók: P (D ) = i U U i, score(x i, U D), (2) ahol U i, az X i valószínűségi változó sorrendezéssel kompatibilis szülői halmazai. A sorrendezések tere n! ezért zárt formában csak kevés változóra tudnánk kiszámolni, ezért alkalmazzuk az MCMC algoritmust. A Markov-láncot úgy hozzuk létre, hogy a stacionárius eloszlása P (D ) legyen. Ezek után bármilyen f( ) függvény várható értékét meg tudjuk határozni a következő módon: E[f D] 1 T f( t ). (3) T 1.4. Eddigi eredmények Az előző félévben az MPI (Message Passing Interface) segítségével egy globális gyorsítótárat hoztunk létre, ami lehetővé tette, hogy a párhuzamosan futó szimulációk megosszák egymással a már kiszámolt score-okat, ezzel csökkentve az egy processzre eső score számítást. t=1 2

Eredmények 139 változó esetében: teszt lokális cache elosztott cache (6 klienssel) elosztott cache (12 klienssel) futásidő 13 568s 5 938s 5 349s A globális gyorsítótár segítségével több, mint kétszeres gyorsulást sikerült elérni. 1.5. OpenCL Az MPI verzió futási idejének fele score számítással telt, ezt szeretnénk most optimalizálni, felgyorsítani. Az MPI azonos gépen lévő processzek esetén nem hatékony megoldás, ezért OpenCLre váltottunk, részben annak reményében, hogy a GPU erősen párhuzamos számításokra készült architektúráját kihasználjuk. Az OpenCL (Open Computing Language) párhuzamos programozás támogatására egy keretrendszert nyújt, amely heterogén platformokon fut (CPU, GPU, FPGA,... ). Programnyelve a C99 szabványon alapul, azt a függvényt, ami az OpenCL eszközön fut kernelnek nevezzük. Előnyei: Az OpenCL programok futásidőben fordulnak, az adott eszköz teljes utasításkészletét ki tudják használni, ezt C-ben csak hardverspecifikusan, többletmunkával tudnánk megtenni. A futásidőben megadott változókat konstansként tudjuk kezelni, ami további optimalizációt tesz lehetővé, például elágazás és cikluskifejtés. Vektoros műveletek támogatása. Az optimális kód létrehozását segíti, ezzel hatékonyan ki tudjuk használni az SIMD (single instruction, multiple data) egységeket. Automatikusan skálázódik a rendelkezésre álló erőforrások szerint. Szinkronizálás, végrehajtási sorok, események támogatása. 2. Tervezés és implementálás 2.1. Alapvető technikák Az egyik alapvető technika a memória elérés optimalizálása. A cache-miss nagyon drága, a gyorsítótárból pár ciklus alatt elérhető az adat, amíg a memóriából csak több, mint 100 ciklus alatt tölthető be. Az összetartozó adatokat tehát tartsuk egymáshoz közel a memóriában, és próbáljuk meg a lehető legtöbb műveletet végrehajtani rajta, amíg a cache-ben található. A másik népszerű technika az SIMD (Single Instruction, Multiple Data) egységek kihasználása. Ez SSE (Streaming SIMD Extensions) esetén 8 darab 128 bites regisztert, míg az újabb processzorokon (Intel: Sandy Bridge, AMD: Bulldozer) megtalálható AVX (Advanced Vector Extensions) 16 darab 256 bites regisztert jelent. 3

típus SSE AVX byte 16 32 short 8 16 int, float 4 8 long long, double 2 4 A fenti táblázatban látható, hogy milyen típusok esetén egyszerre hány adaton tudjuk elvégezni ugyanezt a műveletet. Az SIMD egységek kihasználásával tehát jelentős gyorsulást érhetünk el. A vektoros utasításkészlet alkalmazásakor nagyon fontos az adatok folytonos tárolása és igazított elérése. Ez azt jelenti, hogy az adatunk memóriacíme az igazítás egész számú többszörösére esik. Vektoros regiszterekbe 16 byte-os igazítással kétszer-háromszor gyorsabban lehet betölteni az adatokat. Gondoskodni kell tehát a megfelelő igazításról, erre a következő segédfüggvényeket használtam: 1 void aligned_malloc ( s i z e _ t s i z e, s i z e _ t alignment ) { 2 void ptr, a l i g n e d P t r ; 3 4 ptr = malloc ( s i z e alignment 1 s i z e o f ( void ) ) ; 5 i f (! ptr ) return NULL; 6 7 a l i g n e d P t r = ( void ) ( ( ( i n t p t r _ t ) ptr s i z e o f ( void ) alignment 1) 8 & ~( alignment 1) ) ; 9 ( ( void ) alignedptr 1) = ptr ; 10 11 return a l i g n e d P t r ; 12 } 13 void a l i g n e d _ f r e e ( void a l i g n e d P t r ) { 14 f r e e ( ( ( void ) alignedptr 1) ) ; 15 } Annyi memóriát kérünk, hogy biztosan el tudjuk tolni egy igazított címre, illetve egy mutatónyi területet fenn kell hogy tartsunk adminisztrációs célra, mert csak ezzel a címmel tudjuk felszabadítani a memóriát. GPU esetén 32, 64, 128 byte-os igazított tranzakcióban történik a memória elérés, így itt különösen fontos, hogy az adatok igazítottan és folytonosan helyezkedjenek el, máskülönben jelentősen lecsökken az elérhető sávszélesség. Véletlenszerű elérés esetén az olvasás 16-szor lesz lassabb, mint optimális esetben. GPU esetén a ciklusok és elágazások is érezhető lassuláshoz vezethetnek. A divergens szálak jelentősen csökkentik a teljesítményt, mert azokat a vezérlőnek sorosítania kell. 2.2. Score számítás gyorsítása A score számítás egyszerű műveletek sorozata, amit jól tudunk vektoros műveletekké alakítani. A vektorokban az adott valószínűségi változóhoz tartozó adatok fognak szerepelni, így egy sor áráért 8, illetve AVX támogatás esetén 16 sort tudunk feldolgozni. GPU esetén azt is biztosítjuk ezzel, hogy igazított 32 byte-os tranzakciókban érjük el a memóriát, így a sávszélesség optimálisan lesz kihasználva. Ehhez a bemeneti adatfájlt transzponálni kell. d 1,1 d 1,2 d 1,3 d 1,nSamples padding d 2,1 d 2,2 d 2,3 d 2,nSamples padding d 3,1 d 3,2 d 3,3 d 3,nSamples padding............ padding d nv ariables,1 d nv ariables,2 d nv ariables,3 d nv ariables,nsamples padding 4

Gondoskodnunk kell a valószínűségi változók első adataihoz tartozó memóriacímek helyes igazításáról (d 1,1, d 2,1,..., d nv ariables,1 ). Ehhez igazított allokációt kell használnunk, és a sorokat ki kell egészíteni úgy, hogy a mérete az igazítás egész számú többszöröse legyen. Azt, hogy az adattömbünk mindig elérhető legyen a cache-ben úgy tudjuk biztosítani, hogy a score tábla generálást még az MCMC szimuláció megkezdése előtt elvégezzük. Ha ezt nem tudjuk megoldani, például a hatalmas tár és időigény miatt (lásd 2.4), akkor gyűjtsünk össze annyi hiányzó score-t, amennyit csak tudunk, majd egy lépésben számoljuk ki őket. A feldolgozás sebességén még gyorsíthatunk, ha minden lehetséges szülői halmazszámra külön kernelt fordítunk. Ekkor ugyanis a fordító képes a belső ciklust kifejteni, ami GPU esetén jelentős gyorsulást eredményez. 2.3. Score indexelés A már kiszámolt score-ok tárolásához és gyors előhívásához le kell képeznünk egy {változó, szülőhalmaz} konfigurációt egy egyedi indexre, lehetőleg folytonosan, annak érdekében, hogy minél kisebb méretű tömböt tudjunk címezni vele. Szerencsére ezt a feladatot meg lehet oldani optimális módon az l-binomiális számábrázolást felhasználva. Minden egész szám egyértelműen felbontható binomiális együtthatók összegére. Például a 27 felbontása l = 4 esetén: 27 = ( ) 6 4 ( ) 5 3 ( ) 2 2 ( ) 1. 1 Ezt felhasználva a következőképpen tudjuk egyértelműen leképezni az {X i, P a(x i )} konfigurációt: ( ) [( ) ( ) ( ) ( )] n 1 P a(xi ) 1 P a(xi ) 2 P a(xi ) 3 P a(xi ) 4 index = X i, (4) 4 4 3 2 1 ahol P a(x i ) 1 > P a(x i ) 2 > P a(x i ) 3 > P a(x i ) 4. A fenti módszer akkor képez le optimálisan a [0, n ( (n 1)) k ] intervallumra, ha a P a(xi ) j > Xi elemeket P a(x i ) j 1-el helyettesítjük. A különböző szülőhalmaz méreteket eltolással tudjuk egy tömbben tárolni: ( ) maxp arents P a(x n 1 i ) 1 ( ) P a(x n 1 i ) ( ) index = X i P a(xi ) k, (5) k k P a(x i ) k k=0 ahol n a változók száma. k=0 k=0 2.4. Score cache mérete Az alábbi táblázatban a tábla mérete és a feltöltéséhez szükséges idő található maximálisan három illetve négy szülőszám esetén: 5

max P a = 3 max P a = 4 változószám tárigény időigény tárigény időigény 10 5240 B 20.96 ms 10 kb 59.11 ms 20 90 kb 371.52 ms 393 kb 2.32 s 30 479 kb 1.96 s 3262 kb 19.21 s 40 1550 kb 6.35 s 14 MB 84.80 s 50 3838 kb 15.72 s 44 MB 266.26 s 60 8034 kb 32.91 s 112 MB 11.26 min 70 14 MB 61.39 s 245 MB 24.67 min 80 25 MB 105.27 s 483 MB 48.60 min 90 40 MB 169.30 s 878 MB 88.29 min 100 61 MB 258.88 s 1497 MB 150.50 min 110 90 MB 6.33 min 2425 MB 243.69 min 120 128 MB 8.99 min 3763 MB 6.30 h 130 177 MB 12.41 min 5637 MB 9.44 h 140 239 MB 16.71 min 8192 MB 13.72 h 150 315 MB 22.06 min 11 GB 19.43 h 160 408 MB 28.59 min 15 GB 26.89 h 170 521 MB 36.48 min 21 GB 36.49 h 180 656 MB 45.89 min 28 GB 48.66 h 190 815 MB 57.02 min 37 GB 63.87 h 200 1002 MB 70.06 min 48 GB 3.44 nap 210 1219 MB 85.22 min 61 GB 4.40 nap 220 1469 MB 102.71 min 77 GB 5.56 nap 230 1756 MB 122.77 min 97 GB 6.96 nap 240 2083 MB 145.63 min 120 GB 8.61 nap 250 2454 MB 171.55 min 148 GB 10.58 nap 260 2872 MB 200.78 min 180 GB 12.88 nap 270 3341 MB 233.60 min 217 GB 15.57 nap 280 3866 MB 270.28 min 261 GB 18.69 nap 290 4450 MB 5.19 h 311 GB 22.29 nap 300 5098 MB 5.94 h 369 GB 26.42 nap Látható, hogy amíg maximálisan három szülőszámmal egzakt keresés esetén is belátható időn belül végzünk, addig négy szülő esetén a tárigény jelentősen nő. Erre megoldás lehet az, ha csak három szülőig számolunk egzakt módon, utána pedig közelítő algoritmusokat alkalmazunk. A négy szülős konfigurációk score-jait pedig csak akkor számoljuk ki, amikor szükség van rájuk. 2.5. Szülői halmazok generálása A szülői halmazok generálását szeretnénk párhuzamosan elvégezni. Az lenne az ideális, ha csak egy halmaz kezdő és végső indexét kéne megadni. Ez majd jelentősen egyszerűsíti a párhuzamosítást grid környezetben, mert nem terheljük le a hálózatot előre generált halmazok átküldésével. Az algoritmus a fent ismertetett l-binomiális módszer inverze. A fenti példát megfordítva: rendelkezésünkre áll egy m = 27 index és szeretnénk a hozzá tartozó négy elemű halmazt megtudni. Ehhez először megkeressük azt a legnagyobb n számot, amire még ( n 4) m, ez lesz a halmaz egyik eleme, ezután ezt kivonjuk m-ből és a többi elemre is elvégezzük ugyanezt. Az algoritmus implementációja: 6

1 int c = n V a r i a b l e s ; 2 for ( int k = nparents ; k > 0 ; k ) { 3 for ( c ; m_choose ( c, k ) > m; c ) ; 4 m = m_choose ( c, k ) ; 5 p a rents [ k 1] = c ; 6 } Az ( n k) számítás gyorsítására előre kiszámított értékeket használunk. A c meghatározása lineáris kereséssel történik, ez lehetne gyorsabban bonyolultabb kereséssel, de kis n mellett nem nyerünk vele semmit a plusz elágazások miatt. A gyakorlatban a szülőhalmaz generálása úgy történik, hogy beérkezik az X i valószínűségi változó, a lehetséges szülőváltozók halmaza H = {Y : X i Y }, a kezdő- és végső index. Ekkor a fenti módon generált halmazok elemszáma 0 és H 1 között lesz. Ezzel címezve a lehetséges változók tömbjét, megkapjuk a generált halmazt. 2.6. Ordering score számítás gyorsítása Láthattuk hogy a valószínűségi változók szülőhalmazai függetlenül számíthatók, így a score számítást párhuzamosan el tudjuk végezni. Az előző részben azt is láttuk, hogy a halmazok generálását is fel tudjuk bontani, így már nem csak a változók mentén párhuzamosíthatunk. Ez hatékonyabb erőforrás kihasználást tesz lehetővé. Egy fontos megállapítás, hogy a flip MCMC operátor esetén nem kell újraszámolnunk az összes változó score-ját, csak ahol változás történt a szülőhalmazokban. Sőt, ha a cache-elt score kompatibilis az új sorrendezéssel, akkor csak azokat a szülői halmazokat kell legenerálni amelyben az új változó szerepel. Ez jelentős gyorsulást eredményez, főleg akkor, ha a nagy szülőszámú konfigurációkra nem végzünk cachelést. 2.7. Validálás Az OpenCL-es kód rossz debuggolhatósága miatt úgy ellenőrzöm a helyes működést, hogy ugyanazt a függvényt megírom C-ben és összehasonlítom a kimenetüket. Viszont különböző optimalizáció és beépített függvények (például lgamma()) eltérő pontossága miatt a lebegőpontos számok nem lesznek pontosan egyenlők. Első gondolat a relatív hiba használata: result1 result2 result2 < ɛ, ahol result2 > result1. Ezzel az a probléma, hogy nullához közeli számoknál rosszul működik. Az IEEE szabvány szerint a lebegőpontos számok bitmintája lexikografikus sorrendben kell hogy kövessék egymást, ezért alkalmazhatjuk a következő trükköt: 1 bool almosteqf ( f l o a t f1, f l o a t f2, int maxulps ) { 2 return abs ( ( int )&f 1 ( int )&f 2 ) <= maxulps ) 3 } Ahol maxulps f 1 és f 2 között lévő lebegőpontos számok maximális számát jelöli. 7

3. Eredmények 3.1. Futási eredmények Score számítás: eszköz Native C (AMD Phenom II X4 @4.0Ghz) Native C SSE, Cache opt. (AMD Phenom II X4 @4.0Ghz) OpenCL (AMD Phenom II X4 @4.0Ghz) OpenCL (AMD Radeon HD4850) OpenCL (AMD Radeon HD7950) sebesség 3 ms/score 140 µs/score 20 µs/score 110 µs/score 24 µs/score A CPU-n elért 150-szeres (egy magra vetítve 37,5-szörös) gyorsulás biztató eredmény. Ez önmagában kétszeres javulást hoz az MPI-s verzióhoz képest. Az eredményekből az is kiderül, hogy még a csúcskategóriás Radeon HD7950-es videokártya sem képes hozni egy középkategóriás négymagos CPU szintjét. Ez betudható annak, hogy a score számítás alapvetően kevés és egyszerű műveleteken alapul, így a GPU nem tudja hatékonyan átlapolni a magas globális memória késleltetést. Az ordering részét sajnos még nem volt módom tesztelni, mert nem készült el a kód statisztikai része. 3.2. További lépések A célunk, hogy grid környezetben magas változószám mellett hatékonyan tudjuk futtatni a szimulációt. A jelenlegi algoritmust MPI-vel kibővítve nagyfokú párhuzamosítást hozhatunk létre a következő módon: 1. Lefoglalunk X gépet, egy processzel. A gépen történő párhuzamosítás hatékonysági okokból OpenCL-el lesz kivitelezve. 2. Felosztjuk a változókat a gépek között redundáns módon (kis cache esetén minden gépen meglesz a teljes gyorsítótár) 3. A redundáns táblákat tartalmazó gépek felosztják egymás között a táblát, kiszámolják a score-okat, majd adatot cserélnek. 4. Minden Markov-lánchoz választunk egy gépet, aki a láncért lesz felelős. 5. Láncért felelős gépek kiszámolják az új sorrendet, meghatározzák melyik változókat kell kiszámolni és a keresési tér bonyolultságával arányosan (ez fontos, ha a négy változós konfigurációkat csak igény esetén számoljuk ki) a szabad gépekre küldik őket. 6. A segéd gépek legenerálják a szülőhalmazokat, az esetleges hiányzó scoreokat kiszámítják majd visszaküldik a score-ok összegét. 7. A láncért felelős gép megfelelő módon feldolgozza a beérkezett score-okat majd jöhet az újabb MCMC lépés. A feladat felosztása hatékonyan elvégezhető, csak indexeket kell átküldenünk a számítást végző gépekre, nem terheljük a hálózatot. A számítási idő is jól meghatározható, így várhatóan nem lesznek hosszabb üresjáratok az adat megérkezésre várva. 8

Köszönetnyilvánítás Köszönettel tartozom konzulensemnek, Hajós Gergelynek, aki a felmerült problémákra mindig készségesen válaszolt, segítségével hozzájárult a tárgy sikeres teljesítéséhez. Külön köszönet illeti Gézsi Andrást, akinek az ordering MCMC implementációját alapul vettem a program elkészítésénél. 9

Hivatkozások [1] Nir Friedman, Daphne Koller, Being Bayesian About Network Structure, 2000. [2] Dirk Husmeier, Learning Bayesian networks with improved MCMC schemes, Biomathematics & Statistics Scotland. [3] Ian Anderson, Combinatorics of Finite Sets, 1987. [4] Agner Fog, Optimizing software in C, Copenhagen University College of Engineering, 2012. [5] Intel, Writing Optimal OpenCL, Intel R OpenCL SDK version 1.1 Beta, 2011. [6] NVIDIA, OpenCL Best Practices Guide, 2010. 10