cuda c/ c ++ programozás

11
CUDA C/C++ programozás Atomikus műveletek A segédanyag készítése a TÁMOP 4.2.4.A/2-11-1-2012-0001 Nemzeti Kiválóság Program című kiemelt projekt keretében zajlott. A projekt az Európai Unió támogatásával, az Európai Szociális Alap társfinanszírozásával valósul meg.

Upload: sebastian-mathis

Post on 30-Dec-2015

36 views

Category:

Documents


0 download

DESCRIPTION

CUDA C/ C ++ programozás. Atomikus műveletek. A segédanyag készítése a TÁMOP 4.2.4.A/2-11-1-2012-0001 Nemzeti Kiválóság Program című kiemelt projekt keretében zajlott. A projekt az Európai Unió támogatásával, az Európai Szociális Alap társfinanszírozásával valósul meg. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: CUDA C/ C ++ programozás

CUDA C/C++ programozás

Atomikus műveletek

A segédanyag készítése a TÁMOP 4.2.4.A/2-11-1-2012-0001 Nemzeti Kiválóság Program című kiemelt projekt keretében zajlott. A projekt az Európai Unió támogatásával, az Európai Szociális Alap társfinanszírozásával valósul meg.

Page 2: CUDA C/ C ++ programozás

GPU számítási képességek

Számítási képesség ismétlés: Minden GPU-hoz tartozik egy adott számítási képesság.

Pl.: 1.2, 2.0, 3.0

Leírja: Az architektúra főbb jellemzőit.

A GPU által adott lehetőségeket, és szolgáltatásokat.

Inkrementális szolgáltatáslista. A magasabb számítási képességű GPU több

szolgáltatást ad.

Régi elemek nem vesznek el.

Visszafelé kompatibilitás.

Page 3: CUDA C/ C ++ programozás

Fordítás adott számítási képességre

A kód fordításakor jelezni lehet, a fordító számára, hogy:

Mi a minimális szolgáltatáskészlet (számítási képesség) amire fordítani szeretnénk a programot.

Milyen GPU-ra optimalizáljon.

Megadás az nvcc parancssori argumentumával: nvcc –arch=sm_11

A program minimum 1.1-es képességű GPU-n fut.

Miért érdekes ez nekünk? Mert a mai óra anyaga, az atomikus műveletek a 2.0-s

képességtől jönnek be a GPU-ba.

Meg különben sem árt tudni.

Page 4: CUDA C/ C ++ programozás

Konkurens futtatás

A párhuzamos programok futásakor előfordulhatnak versenyhelyzetek:

Két vagy több utasítás ugyanazt az adatot próbálja elérni/módosítani.

Például:__global__ void kernel(int* x) {

(*x)++; // x növelése (nem pixelenként)

return;}

Int main(...) { int* dev_x;

// ...

kernel<<<2, 2>>>(dev_x); // melyik szál növeli x-et?

// ...}

Page 5: CUDA C/ C ++ programozás

Probléma konkurens adatelérésnél

(*x)++;

3 lépésben

X értékének kiolvasása a memóriából,

Az érték növelése,

Eredmény visszaírása a memóriába

Ha párhuzamosan megy (pl.: x):

1. szál

Olvasás:• reg = *x;

// 4 beolvasva

Növelés:• reg++;

// növelt érték: 5

Visszaírás:• *x = reg; // *x=5;

2. szál

Olvasás:• reg = *x;

// 4 beolvasva

Növelés:• reg++;

// növelt érték: 5

Visszaírás:• *x = reg; // *x=5;

3. szál

Olvasás:• reg = *x;

// 4 beolvasva

Növelés:• reg++;

// növelt érték: 5

Visszaírás:• *x = reg; // *x=5;

idő

Page 6: CUDA C/ C ++ programozás

Ugyanaz szekvenciálisan

(*x)++;

3 lépésben

X értékének kiolvasása a memóriából,

Az érték növelése,

Eredmény visszaírása a memóriába

Ha párhuzamosan megy (pl.: x):

1. futás

Olvasás:• reg = *x;

// 4 beolvasva

Növelés:• reg++;

// növelt érték: 5

Visszaírás:• *x = reg; //

*x=5;

2. futás

Olvasás:• reg = *x;

// 5 beolvasva

Növelés:• reg++;

// növelt érték: 6

Visszaírás:• *x = reg; // *x=6;

3. futás

Olvasás:• reg = *x;

// 6 beolvasva

Növelés:• reg++;

// növelt érték: 7

Visszaírás:• *x = reg; // *x=7;

idő

Page 7: CUDA C/ C ++ programozás

Konkurens változónövelés a gyakorlatban

14_RaceCondition.cu

Egy változó érték növelése adott számszor.

Párhuzamosan a GPU-n.

És szekvenciálisan a GPU-n.

Page 8: CUDA C/ C ++ programozás

Atomikus műveletek

Feloldják a konfliktusokat. Biztosított, hogy egyszerre csak egy szál férhessen hozzá egy

adatelemhez.

Műveletek: int atomicAdd(int* address, int val);

int atomicSub(int* address, int val);

int atomicExch(int* address, int val);

int atomicMin(int* address, int val);

int atomicMax(int* address, int val);

unsigned int atomicInc(unsigned int* address, unsigned int val);

unsigned int atomicDec(unsigned int* address, unsigned int val);

int atomicCAS(int* address, int compare, int val);

int atomicAnd(int* address, int val);

int atomicOr(int* address, int val);

int atomicXor(int* address, int val);

Page 9: CUDA C/ C ++ programozás

Valós példa:Hisztogram

Hisztogram számítása a GPU-n.

Adott egy adatsor (diszkrét elemekből).

Pl.: kép egész pixelintenzitásokkal 0 és 255 között.

Megoldása CPU-n.

15_HistCPU.cu

Sima ügy.

unsigned char* adat; int* hiszt[256];

for(int i=0; i<256; i++) hiszt[i] = 0;

for(int i=0; i<adat_meret; i++) hiszt[adat[i]]++;

Page 10: CUDA C/ C ++ programozás

Hisztogram a GPU-n

Bonyolult művelet.

A szálak konkurens módon párhuzamosan dolgozzák fel az adatot.

Konfliktus léphet fel, ha két szál ugyanazt a hisztogram számlálót akarja növelni.

Magoldás: atomikus műveletek

A számláló növeléseket atomikus műveletekkel végezzük a kernelben.

Ez automatikusan feloldja a konfliktusokat.

Hátrányok:

Lassítja a kódot

A szálak sorban várhatnak egy számláló növelésére.

16_Hist_GPU.cu

Page 11: CUDA C/ C ++ programozás

További lehetőségek

Mire lehetne még használni az atomikus műveleteket?