párhuzamos programozás…home.mit.bme.hu/~szell/parhuzamos/todor_balazs... · 2009. 3. 12. ·...

81
Párhuzamos programozás… … a gyakorlatban Tódor Balázs [email protected]

Upload: others

Post on 24-Oct-2020

1 views

Category:

Documents


0 download

TRANSCRIPT

  • Párhuzamos

    programozás…

    … a gyakorlatban

    Tódor Balázs

    [email protected]

  • 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