párhuzamos programozás…home.mit.bme.hu/~szell/parhuzamos/todor_balazs... · 2009. 3. 12. ·...
TRANSCRIPT
-
Párhuzamos
programozás…
… a gyakorlatban
Tódor Balázs
-
Tematika
Erről lesz szó
1 PC
C++
OpenMP, thread-ek
Közös memória
Használati technikák, trükkök
Erről nem
Sok PC (grid, cluster)
C#, Java, Python
MPI, process-ek
Elosztott memóriás modell
Mi a mutex, CS, stb.
-
Tartalom
Párhuzamosítás 1x1
Eszközök, technikák
FP, AP, kommunikáció
Tervezés
Az eddigiek használata
Top-down/Bottom-up
Egy lehetséges jövő
Stream programming
-
Miért?
Hány processzorod van?
A GPU számít?
1 CPU
2, 4, 8,… mag
Moore törvénye: 1,5 évente x2 mag
Kihasználtság
50%, 25%, 13%, …
Core i7 = 8 mag
-
Párhuzamosítás 1x1
Független feladatok azonosítása
Megjelenítés + számolás
Zene + kezelőfelület
Beolvasás + helyesírás
Külön szál minden feladatnak
Eszközök: Intel TBB, boost
Kölcsönös kizárás
printf
Kommunikáció
teljes függetlenség nem szokott lenni
-
Zab és bab
Független feladatok
Zab
Bab
Két külön szál
Eszközök
Boost::thread
OpenMP
Válogatás
BabmosásZabmosás
HámozásHegyezés
Csomagolás Csomagolás
Vége
-
Boost
„STL++”
Platformfüggetlen, ingyenes
Mit tud?
Array, circular buffer, bitset
Graph, FSM
File system, függvénypointerek
Thread, mutex, stb.
Any, variant, konvertálás
String algoritmusok
-
Boost::thread
Thread
Ctor
Join
ThreadFunc
Függvény
N paraméter
Válogatás
BabmosásZabmosás
HámozásHegyezés
Csomagolás Csomagolás
Vége
boost::thread
zabThread(ZabFunc);
zabThread.join();
babThread.join();
boost::thread
babThread(BabFunc);
-
OpenMP
Fordítóba beépített
Intel, MSVC, gcc
Minimális kódmódosítás
„#pragma omp”
Multiplatform
Linux, Win32, stb.
Rugalmas
AP, FP, mutex, CS, single/master, stb.
-
OpenMP
Parallel
OMP
engedélyezése
Sections
Párhuzamos blokk
Section
Szálak
létrehozása
Barrier
Join_all
Válogatás
BabmosásZabmosás
HámozásHegyezés
Csomagolás Csomagolás
Vége
omp parallel
omp sections
omp barrier
omp section omp section
-
OpenMP vs boost
-
OpenMP
-
boost
-
Funkcionális párhuzamosítás
Független funkciók
Kölcsönös kizárás
Kommunikáció
... egyszerű, gyors, rugalmatlan
2x annyi szál?
-
Fizikai szimuláció
Ütköztetés 1.
NxN
R: objektumok
Feloldás
N
R: objektum
W: objektum
dSpaceCollide NearCallback Step
Ütköztetés 2.
NxN
R: objektumpár
W: contact-ok
-
Fizikai szimuláció
Feladatok dSpaceCollide: (1*N)*N
NearCallback: (1*N)*N
Step (1*N)
Független feladatok (collide+near+step)
(collide+near+step)
(collide+near+step)
...
Azonos funkció, sok szál
Rugalmas, egyszerű
De: csak független adatokon
-
Parallel for
Ciklusváltozósigned int
Összehasonlításegyszerű
Léptetéskonstanssal
KiugrásBreak, continue,
goto
fork
join
-
Közös erőforrások
Az írás-olvasás
között más is
beleírhat.
Kölcsönös kizárás
vagy
Csak olvasás
Közös változó
Írás
Olvasá
s
-
Explicit saját változó
Saját változó
-
Implicit saját változó
Saját változó
-
Közös és saját
Egy tömb összes elemét akarjuk
összeadni
Mi legyen a célváltozó?
Közös, mert meg akarjuk tartani
Saját, mert többen is írnának bele
Ha közös?
Kölcsönös kizárás (lassú)
Ha saját?
Eltűnik amit beleírunk!
-
Redukció
Közös változó
Redukció bekapcs.
Implicit: sajátok -> közös
Explicit: saját változó
-
Fizika és AP
Collide
N szál
NearCallback
Ír a contact-ok listájába -> lock
Step
N szál
… máshol keressük a függetlenséget!
-
Fizikai szimuláció:
függetlenség A különböző „szigetek” függetlenek
Számolhatjuk őket külön szálakon
Collide: N*N
PhysX, ODE
Legjobb eset
egyforma szigetek
Legrosszabb eset
N, 1, 1, 1
Ez gyakorlatilag egyszálú
-
Fizikai szimuláció:
függetlenség A különböző „szigetek” függetlenek
Számolhatjuk őket külön szálakon
Collide: N*N
PhysX, ODE
Legjobb eset
egyforma szigetek
Legrosszabb eset
N, 1, 1, 1
Ez gyakorlatilag egyszálú
-
„Legrosszabb eset”
Funkcionális
lassú/gyors eljárások külön szálon
pl. beolvasás + helyesírásellenőrzés
Adat
kevés/sok adat: N, 1, 1, 1
Nem egyforma műveletek
Statikus kiosztás
Hány szál van?
Melyik szál mit csinál?
-
A megoldás
Skálázhatóság
Feladat és végrehajtás külön
Dinamikus erőforráskiosztás
Szálak közötti feladatmozgatás
N, 1, 1, 1 -> N/2, 1+N/2, 1, 1
Lassú, gyors -> gyors+lassú/2, lassú/2
-
Hibrid rendszerek
Taszk
Funkciórész + valamennyi adat
Kicsi: jobb kihasználtság
Nagy: kevesebb szinkronizáció
Ütemező
Taszk-szál összerendelés
Egyszálas (gyors legyen)
Erőforrás
Processzor (szálak)
HDD, user (képernyő, billentyűzet)
-
Fizikai szimuláció: gráfban
-
Ütemezés
Mikor futhat egy taszk?
Bemenet (producer-consumer)
Erőforrásigények
Olvasás/írás?
Gyors, egyszerű
Critical section-ben fut
Amdahl törvénye
-
Amdahl
A „varázsképlet”:
P: párh./soros arány
N: CPU-szám
Jól gondold meg hol lockolsz!
-
Ütemezés
Taszk
list
m_apWriteLocks;
list
m_apReadLocks;
bool CanRun(const
guard&);
CanRun()
Erőforrások
Bemenetek
LOCK
task=list.front()
task.CanRun()
list.move(task, vége) list.pop_front()
UNLOCK
Task.Run()
true false
-
Hibrid rendszerek
A végrehajtás és a feladat független
Skálázható
Legyen elég taszk
Logikus: irányított gráfból hozható létre
-
Párhuzamosítás 1x1
Független feladatok azonosítása
Szálak létrehozása
Kölcsönös kizárás
Olvasás, írás
Kommunikáció
Közös erőforrások
Kommunikáció
Producer-consumer
-
Kölcsönös kizárás
Olvasás vs írás
Olvasni: akárhányan
Írni: csak egy
Tanulság: olvasni jó
HL2 (Source): 95%
Eszközök
Mutex, Critical Section, stb.
Egyik sem biztonságos
De mindegyik lassú
-
Kommunikáció
Nincs kizárás
Atomi műveletek
Lockless
Hardware-es kölcsönös kizárás
Kölcsönös kizárás
Mutex, CS, stb.
Kettős pufferelés
Igazi garázsbaillő megoldás
-
Atomi megoldások
Hardverfüggő
1 db aligned read/write mindig atomi
iValue = 0;
++a
Beolvasás+növelés+visszaírás = 3
OpenMP: 'atomic' kulcsszó
Több atomi művelet?
-
Több atomi művelet
Tipikus hiba
iData = 5; bValidData = true;
Ellenségünk: instruction reordering
Az MMU blokkokban írja a memóriát
Főleg XBox, de PC-n is előfordul
Megoldás
Critical section
Platformfüggő: barrier utasítások
-
Lockless
„Lock”
Lock, tárolás, unlock
Lassú, ismert, biztonságos
„Lockless”
CompareAndSwap utasítás
Sok lock megoldás erre épül
-
Lockless
Láncolt lista
old=NULL
CAS(head, old, new)
false -> head=old, újra
Tulajdonságok
Gyors (hardveres)
Végrehajtási idő?
Prioritások?
ABA-probléma
A != A
-
ABA-probléma
A probléma
Thread1: A->B->A
Thread2: CAS(&p, A, C)=true
Mikor jön elő?
Az ‘A’ érték nem a teljes állapotot tárolja(A!=A)
Pl. A = pointer
A megoldás
32b: DCAS: 64 bit (32b pointer + azonosító)
64b: aligned pointerek + bitbuherálás
-
ABA-probléma: láncolt lista
A lista
struct { Obj* next; } *
Eredetileg: A, B
Műveletek
Thread1: read A (nincs pop)
Next = A.next (B)
Thread2: pop A, pop B, push A
A.next = NULL
Thread1: CAS(head, A, C)
true, de C.next = B !
-
Lockless: miért jó?
Nincs deadlock (és ez a helyes megoldás?!)
Nincs prioritásinverzió
Prioritásörökléssel is megoldható
Mondjuk itt prioritás sincs…
Nincs sorbanállás „… a kamion a leggyorsabb”
Interrupt handler
Malloc, interrupt, a handler-ben malloc?
Hatékonyabb, mint a mutex
Nagy méretű tömb esetén hogy lockolsz?
-
Szünet
Végig maradt Szünetben hazament
-
Párhuzamos problémák
Instruction reordering
A=5; B=1; -> B=1; A=5;
CS, barrier
Változók regiszterekben
„Tudatlan” fordítók
Volatile kulcsszó
False sharing
Nem hiba, csak lassú
-
False sharing
Struct: A, B elemek
Thread1: A-t használja
Thread2: B-t használja
Helyesen működik
Független feladatok
Nem kell kölcsönös kizárás
Rém lassú… miért?
-
False sharing
Thread1: A=1;
Cache line „piszkos”
Core2: cache line „érvénytelen”
Thread2: ++B
L1 Cache line „érvénytelen”
Újraolvasás: RAM->L2->L1->B
Megoldás:
Egy cache line = egy core
-
Kettős pufferelés
Memóriaigényes: két példány
Késik egy „swap”-et
Nincs lock
Kivéve: swap
Hatékony
Funkcionálisan párhuzamos rendszerek
Erősen összekötött rendszerek
-
Intel „Smoke”
Rendszerek: MI, fizika, grafika, hang, input
Az FP a legszebb, de…
Fizika -> MI, gfx, hang
gfx -> MI
Input->fizika
Change manager
Inkább késsen, mint lockoljon
„Kettős puffer továbbfejlesztve”
-
Intel „Smoke”
FP volt, hibrid lett
1 nagy feladat = sok (soros) taszk
Egyszerűbb, mint a teljes párhuzamosítás
A rendszerenkénti futási idő nem változik
De jobb kitöltés -> „párhuzamosíthatóbb”
-
Intel „Smoke”
Observer: Saját másolat a közös objektumokból Nincs lock, amikor olvasol
Cserébe késik az információ
Change Controller: per frame szinkronizáció 1 frame késés
Sok rendszer?
-
Intel „Smoke”
Fix időnként átviszi a változásokat
Clock: game clock (lehet renderfüggetlen)
-
Lock technikák
Hol lockolunk?
„adathoz v. kódhoz” közel
Lock helyett guard
Private változók = nincs lock!
Thread Local Storage
„Multithreaded Singleton”
A mutex:adat arány
1:1, N:1, 1:N
-
Hol lockoljunk?
Működik?
Igen
Bővíthető?
Nehezen
(Enter/Leave)
Skálázható?
Nehezen (FP)
lock
unlock
-
Hol lockoljunk?
Van egy osztály... több szál akarja használni.
nem thread safe
nem thread safe
-
Hol lockoljunk?
Külső lock
Majd megoldja valaki…
+3 nap debuggolás / osztály (~270eFt)
Belső lock
Az osztály magának elintézi
Esetek 90%-a
Hívó által biztosított
A hívónak bizonyítania kell, hogy lockolt
Ez a +10%
-
Belső lock
Biztonságos
Teljesen thread safe
„Idiótabiztos”
Kívülről láthatatlan
Bárki használhatja az osztályt
Rugalmatlan
Annyi lock, ahány művelet.
guard
guard
-
Hívó által
bizonyíték
-
Hívó által
Nem az igazi...
Mit bizonyít egy lock_guard?
Kinek a mutexe?
Továbbfejlesztési lehetőségek
Típusos lock_guard
Lock_guard
Fordítási idejű ellenőrzés
Pointeres lock_guard
Lock_guard.m_pOwner
Futási idejű ellenőrzés
-
1:1
1 adat, 1 mutex
Lock: minél közelebb
Erre van a Get/Set
Tömbök?
-
1:N
„Modulo N” lockolás:
pl. páros/páratlan
Mitől függ az N?
Szálak száma
Egy szál hány elemhez fér hozzá egyszerre
-
Hívó általi lock
1 lock, N művelet
Ez is 1:N!
Gyorsabb… de „egyszálúbb”
explicit lock
implicit unlock
-
N:1
Több mutex egy adathoz?
„A” szál lefogja az egyiket...
„B” szál a másikat...
Sok-sok debuggolás…
Intel Thread Checker
1000 USD
-
Tartalom
Párhuzamosítás 1x1
Eszközök, technikák
FP, AP, kommunikáció
Tervezés
Az eddigiek használata
Top-down/Bottom-up
Egy lehetséges jövő
Stream programming
-
Hogyan párhuzamosítsunk?
Hol kell párhuzamosítani?
Leglassabb részek keresése
90/10-es szabály
Független feladatok azonosítása
Sugárkövetés
Videófeldolgozó program
-
Megközelítés
Top-down
rendszerszinttől, lefelé
Bottom-up
közvetlenül ott, ahol szükséges
„Call stack” módszer
Breakpoint a 10%-ba
Melyik szinten érdemes próbálkozni?
-
Példa
Független részek
Pixelek
Leglassabb
Sugár-test metszés
Top-down
Pixelek
Bottom-up
Testek
Sugarak
Független részek
Pixelek
Képkockák
Leglassabb
Motion blur
Top-down
Képkockák
Bottom-up
Pixelek
-
Előre tervezés
Milyen új funkciók lehetnek?
Mit kéne tudnia egy év múlva?
Milyen új adatok lehetnek?
Több?
Más?
Merre fejlődik a hardver?
Több mag
SIMD, SIMT
-
Előre tervezés
Általában több adat kerül be mint funkció
Videófeldolgozás
A frame-ek száma gyorsabban nő, mint a
pixeleké
Raytracer
Szebb képhez több sugár/test ütközés kell
Kompromisszum?
FP mellett OpenMP-s AP
Mindegy mit csinálsz, az OpenMP még belefér
-
Párhuzamos optimalizáció
Ami gyors egy szálon, az nem biztos, hogypárhuzamosítható is.
Mátrixszorzás:
Triviális: O(n3)
Strassen: O(n2,81)
-
Mátrixszorzás
Triviális
4 szál
Azonos terhelés
Strassen
7 szál, aztán 4
Eltérő terhelés
Soros rész!
-
Tartalom
Párhuzamosítás 1x1
Eszközök, technikák
FP, AP, kommunikáció
Tervezés
Az eddigiek használata
Top-down/Bottom-up
Egy lehetséges jövő
Stream programming
-
A jövő
Intel core i7
8 mag
GPU
8800 GTS = 112 mag (GTX 280: 240)
Nem csak grafikára
Hogyan programozzuk? HLSL, BrookGPU
CUDA / AMD Stream
OpenCL
C++ (Larrabee)
-
Stream programming
HLSL, Brook Pixel shader, adat=textúra, kimenet=rendertarget
1 helyre írás
CUDA/Stream „Scatter write”
Gyártófüggő
OpenCL AMD, Apple, nVidia, stb.
2009
Larrabee > 25 db P54C
C++
… „Linux a videókártyán”
-
Stream programming
(olvas, feldolgoz, ír)xN
Sok, független adat (N>1000)
Teljesen azonos feldolgozás (SIMT)
Divergencia?
Mi hiányzik?
Rekurzió
Pointerek
Össze-vissza írás/olvasás
Feltételek/ugrások
-
CUDA
Szálkezelés
Buta, gyors (~1000)
SIMT
Adatkezelés
Tömb (textúra)
Konstans tömb
Háromszintű memória
Kommunikáció
Barrier (__syncthreads)
CPU-s emuláció
printf
-
CUDA
ThreadID adat index
Közös memória Local: blokkon belül
Global: grid-en belül
Barrier Blokkon belül
Kernel float *pIn, *pOut (stream!)
Adat: pIn[threadID]
-
CUDA példa
Thread ID
Kernelhívás
-
Összefoglalás
Funkcionális vagy adatpárhuzamosítás FP: ha független funkciók vannak
AP: ha sok független adat van
N~1000 -> stream
Hibrid rendszerek Adatfolyamgráfból -> Taszk + ütemező
OpenMP-vel FP/AP együtt
Kommunikáció, lock Atomi/Lockless/lock
adathoz közel
-
Elérhetőség
Letöltés
www.mit.bme.hu/~szell/parhuzamos
Kérdések
Tódor Balázs, [email protected]
http://www.mit.bme.hu/~szell/parhuzamoshttp://www.mit.bme.hu/~szell/parhuzamoshttp://www.mit.bme.hu/~szell/parhuzamoshttp://www.mit.bme.hu/~szell/XY
-
Köszönöm a figyelmet!
A. Alexandrescu: „Multithreading and the C++ Type System”
T. Refenes: „How to Start a Multi-Threading RelationShip”
C. Breshears: „8 Simple Rules for Designing Threaded Applications”
T. Mattson, L. Meadows: “A „Hands-on‟ Introduction to OpenMP”
Intel: „Designing the Framework of a Parallel Game Engine”
T. Leonard (Valve): „Dragged Kicking and Screaming: Source Multicore”
Bruce Dawson (XNA): „Multicore Memory Coherence: The Hidden Perils of Sharing Data”
Cyril Zeller(nVidia): „CUDA Tutorial”
Jon Olick (id): „Current Generation Parallelism In Games”
Ian Buck (nVidia): „Programming CUDA”
Intel: „Smoke demo”
ODE: Open Dynamics Engine
Boost C++ libraries
Khronos Group: OpenMP, OpenCL
Geoff Langdale: „Lock-Free Programming”
Wikipedia: „Strassen algorithm”
http://www.informit.com/articles/article.aspx?p=25298http://www.informit.com/articles/article.aspx?p=25298http://www.informit.com/articles/article.aspx?p=25298http://www.informit.com/articles/article.aspx?p=25298http://www.informit.com/articles/article.aspx?p=25298http://www.gamasutra.com/view/feature/3885/sponsored_feature_how_to_start_a_.phphttp://www.gamasutra.com/view/feature/3885/sponsored_feature_how_to_start_a_.phphttp://www.gamasutra.com/view/feature/3885/sponsored_feature_how_to_start_a_.phphttp://www.gamasutra.com/view/feature/3885/sponsored_feature_how_to_start_a_.phphttp://www.gamasutra.com/view/feature/3885/sponsored_feature_how_to_start_a_.phphttp://www.gamasutra.com/view/feature/3885/sponsored_feature_how_to_start_a_.phphttp://www.gamasutra.com/view/feature/3885/sponsored_feature_how_to_start_a_.phphttp://www.gamasutra.com/view/feature/3885/sponsored_feature_how_to_start_a_.phphttp://www.gamasutra.com/view/feature/3885/sponsored_feature_how_to_start_a_.phphttp://software.intel.com/en-us/articles/8-simple-rules-for-designing-threaded-applications/http://software.intel.com/en-us/articles/8-simple-rules-for-designing-threaded-applications/http://software.intel.com/en-us/articles/8-simple-rules-for-designing-threaded-applications/http://software.intel.com/en-us/articles/8-simple-rules-for-designing-threaded-applications/http://software.intel.com/en-us/articles/8-simple-rules-for-designing-threaded-applications/http://software.intel.com/en-us/articles/8-simple-rules-for-designing-threaded-applications/http://software.intel.com/en-us/articles/8-simple-rules-for-designing-threaded-applications/http://openmp.org/mp-documents/omp-hands-on-SC08.pdfhttp://openmp.org/mp-documents/omp-hands-on-SC08.pdfhttp://openmp.org/mp-documents/omp-hands-on-SC08.pdfhttp://openmp.org/mp-documents/omp-hands-on-SC08.pdfhttp://openmp.org/mp-documents/omp-hands-on-SC08.pdfhttp://openmp.org/mp-documents/omp-hands-on-SC08.pdfhttp://openmp.org/mp-documents/omp-hands-on-SC08.pdfhttp://openmp.org/mp-documents/omp-hands-on-SC08.pdfhttp://openmp.org/mp-documents/omp-hands-on-SC08.pdfhttp://openmp.org/mp-documents/omp-hands-on-SC08.pdfhttp://openmp.org/mp-documents/omp-hands-on-SC08.pdfhttp://openmp.org/mp-documents/omp-hands-on-SC08.pdfhttp://software.intel.com/en-us/articles/designing-the-framework-of-a-parallel-game-engine/http://software.intel.com/en-us/articles/designing-the-framework-of-a-parallel-game-engine/http://software.intel.com/en-us/articles/designing-the-framework-of-a-parallel-game-engine/http://www.valvesoftware.com/publications/2007/GDC2007_SourceMulticore.pdfhttp://www.valvesoftware.com/publications/2007/GDC2007_SourceMulticore.pdfhttp://www.valvesoftware.com/publications/2007/GDC2007_SourceMulticore.pdfhttp://www.valvesoftware.com/publications/2007/GDC2007_SourceMulticore.pdfhttp://www.valvesoftware.com/publications/2007/GDC2007_SourceMulticore.pdfhttp://www.valvesoftware.com/publications/2007/GDC2007_SourceMulticore.pdfhttp://www.valvesoftware.com/publications/2007/GDC2007_SourceMulticore.pdfhttp://www.valvesoftware.com/publications/2007/GDC2007_SourceMulticore.pdfhttp://www.microsoft.com/downloads/details.aspx?FamilyId=E6B38940-7EE3-45C4-AF07-BD6C09804847&displaylang=enhttp://www.microsoft.com/downloads/details.aspx?FamilyId=E6B38940-7EE3-45C4-AF07-BD6C09804847&displaylang=enhttp://www.microsoft.com/downloads/details.aspx?FamilyId=E6B38940-7EE3-45C4-AF07-BD6C09804847&displaylang=enhttp://www.microsoft.com/downloads/details.aspx?FamilyId=E6B38940-7EE3-45C4-AF07-BD6C09804847&displaylang=enhttp://www.microsoft.com/downloads/details.aspx?FamilyId=E6B38940-7EE3-45C4-AF07-BD6C09804847&displaylang=enhttp://www.microsoft.com/downloads/details.aspx?FamilyId=E6B38940-7EE3-45C4-AF07-BD6C09804847&displaylang=enhttp://www.microsoft.com/downloads/details.aspx?FamilyId=E6B38940-7EE3-45C4-AF07-BD6C09804847&displaylang=enhttp://people.maths.ox.ac.uk/~gilesm/hpc/NVIDIA/NVIDIA_CUDA_Tutorial_No_NDA_Apr08.pdfhttp://people.maths.ox.ac.uk/~gilesm/hpc/NVIDIA/NVIDIA_CUDA_Tutorial_No_NDA_Apr08.pdfhttp://people.maths.ox.ac.uk/~gilesm/hpc/NVIDIA/NVIDIA_CUDA_Tutorial_No_NDA_Apr08.pdfhttp://people.maths.ox.ac.uk/~gilesm/hpc/NVIDIA/NVIDIA_CUDA_Tutorial_No_NDA_Apr08.pdfhttp://people.maths.ox.ac.uk/~gilesm/hpc/NVIDIA/NVIDIA_CUDA_Tutorial_No_NDA_Apr08.pdfhttp://people.maths.ox.ac.uk/~gilesm/hpc/NVIDIA/NVIDIA_CUDA_Tutorial_No_NDA_Apr08.pdfhttp://people.maths.ox.ac.uk/~gilesm/hpc/NVIDIA/NVIDIA_CUDA_Tutorial_No_NDA_Apr08.pdfs08.idav.ucdavis.edu/olick-current-and-next-generation-parallelism-in-games.pdfs08.idav.ucdavis.edu/olick-current-and-next-generation-parallelism-in-games.pdfs08.idav.ucdavis.edu/olick-current-and-next-generation-parallelism-in-games.pdfs08.idav.ucdavis.edu/olick-current-and-next-generation-parallelism-in-games.pdfs08.idav.ucdavis.edu/olick-current-and-next-generation-parallelism-in-games.pdfs08.idav.ucdavis.edu/olick-current-and-next-generation-parallelism-in-games.pdfs08.idav.ucdavis.edu/olick-current-and-next-generation-parallelism-in-games.pdfhttp://www.gpgpu.org/sc2007/SC07_CUDA_2_Language_Buck.pdfhttp://www.gpgpu.org/sc2007/SC07_CUDA_2_Language_Buck.pdfhttp://www.gpgpu.org/sc2007/SC07_CUDA_2_Language_Buck.pdfhttp://www.gpgpu.org/sc2007/SC07_CUDA_2_Language_Buck.pdfhttp://www.gpgpu.org/sc2007/SC07_CUDA_2_Language_Buck.pdfhttp://www.gpgpu.org/sc2007/SC07_CUDA_2_Language_Buck.pdfhttp://software.intel.com/en-us/articles/smoke-game-technology-demo/http://software.intel.com/en-us/articles/smoke-game-technology-demo/http://software.intel.com/en-us/articles/smoke-game-technology-demo/http://software.intel.com/en-us/articles/smoke-game-technology-demo/http://software.intel.com/en-us/articles/smoke-game-technology-demo/http://software.intel.com/en-us/articles/smoke-game-technology-demo/http://www.ode.org/http://www.ode.org/http://www.boost.org/http://www.boost.org/http://www.boost.org/http://www.boost.org/http://www.openmp.org/http://www.khronos.org/opencl/http://www.cs.cmu.edu/~410-s05/lectures/L31_LockFree.pdfhttp://www.cs.cmu.edu/~410-s05/lectures/L31_LockFree.pdfhttp://www.cs.cmu.edu/~410-s05/lectures/L31_LockFree.pdfhttp://www.cs.cmu.edu/~410-s05/lectures/L31_LockFree.pdfhttp://www.cs.cmu.edu/~410-s05/lectures/L31_LockFree.pdfhttp://www.cs.cmu.edu/~410-s05/lectures/L31_LockFree.pdfhttp://www.cs.cmu.edu/~410-s05/lectures/L31_LockFree.pdfhttp://www.cs.cmu.edu/~410-s05/lectures/L31_LockFree.pdfhttp://www.cs.cmu.edu/~410-s05/lectures/L31_LockFree.pdfhttp://en.wikipedia.org/wiki/Strassen_algorithmhttp://en.wikipedia.org/wiki/Strassen_algorithmhttp://en.wikipedia.org/wiki/Strassen_algorithmhttp://en.wikipedia.org/wiki/Strassen_algorithmhttp://en.wikipedia.org/wiki/Strassen_algorithmhttp://en.wikipedia.org/wiki/Strassen_algorithmhttp://en.wikipedia.org/wiki/Strassen_algorithm