Professional Documents
Culture Documents
Instalare
Utilizare
Elemente cheie
Fork-join
Setare numar thread-uri din program, la o valoare diferita de cea detectata automat de OpenMP:
omp_set_num_threads(int nr_threads) sau export OMP_NUM_THREADS=nr_threads
API
Generala
Tip
Nume directiva
parallel
Work-sharing
for
Efect
Hello
Hello
Hello
Hello
0 1 2 3 4
Lucrul util facut in cadrul unei bucle este impartit intre toate threadurile. Fiecare thread va primi cate o iteratie a for-ului.
sections
Marcheaza o sectiune de cod ce se va executa independent de cate un
thread
World!
World!
World!
World!
section
}
1/4
Work-sharing
Tip
Nume directiva
Efect
single
#pragma omp
#pragma omp
for (i = 0;
a[i] +=
barrier
for
i < 5; i++)
i;
in master: thread id = 0
a[0] = 0
a[1] = 1
a[2] = 4
a[3] = 9
a[4] = 16
-----thread id = 2
thread id = 3
thread id = 0
thread id = 1
-----in master: thread id = 0
a[0] = 0
a[1] = 2
a[2] = 6
a[3] = 12
a[4] = 20
Sincronizare
critical
//SIZE=10; a=[1,2,3,4,5,6,7,8,9,10]
max = a[0];
#pragma omp parallel for
for (i = 1; i < SIZE; i++)
{
if (a[i] > max)
{
#pragma omp critical
{
if (a[i] > max)
max = a[i];
}
}
}
printf("max = %d\n", max);
max = 10
2/4
Sincronizare
Tip
Nume directiva
atomic
Efect
int count = 0;
#pragma omp parallel
{
#pragma omp atomic
count++;
}
printf("count=%d\n", count);
count=2
2. CLAUSE
Nume clauza
private (VARIABLES)
shared (VARIABLES)
Efect
int v = 100;
printf("before block: %d\n", v);
#pragma omp parallel private(v)
{
printf("in block: %d\n", v);
}
printf("after bloc: %d\n", v);
//a = [0,1]
//b = [0,1]
#pragma omp parallel shared(a,b,c,chunk)
{
int tid = omp_get_thread_num();
for (int i=0; i < N; i++)
{
c[i] = a[i] + b[i];
printf("tid=%d i=%d c[i]=%d\n",tid,i,c[i]);
}
}
tid=0
tid=0
tid=3
tid=3
tid=2
tid=2
tid=1
tid=1
i=0
i=1
i=0
i=1
i=0
i=1
i=0
i=1
c[i]=0
c[i]=2
c[i]=0
c[i]=2
c[i]=0
c[i]=2
c[i]=0
c[i]=2
Programatorul alege felul in care variabilele sunt vazute in toate thread-urile din bloc. ATENTIE! Implicit, toate variabilele sunt shared!
int v = 100;
printf("before block: %d\n", v);
#pragma omp parallel firstprivate(v)
{
printf("in block: %d\n", v);
}
printf("after block: %d\n", v);
lastprivate (VARIABLES)
int v = 100;
printf("before block: %d\n", v);
#pragma omp parallel for firstprivate(v) lastprivate(v)
for (int i = 0; i<2; i++)
{
v+=1;
}
printf("after block: %d\n", v);
reduction(OPERATION:VARIABLES)
sum = 14
firstprivate (VARIABLES)
3/4
Nume clauza
Efect
num_threads(NUMBER)
schedule(TYPE:[CHUNK-SIZE])
if(CONDITION)
void main() {
#pragma omp parallel num_threads(8)
{
int i = omp_get_thread_num();
printf("Hello from thread %d\n", i);
}
}
from
from
from
from
from
from
from
from
thread
thread
thread
thread
thread
thread
thread
thread
1
5
0
7
4
3
6
2
void main( )
{
test(0);
test(2);
}
Lock-uri OpenMP. Un lock (mutex) este un mecanism de sincronizare pentru a limita accesul la o resursa, intr-un mediu in care se executa mai multe thread-uri
Apel
omp_lock_t NAME
omp_init_lock(&NAME)
omp_set_lock(&NAME)
omp_unset_lock(&NAME)
omp_test_lock(&NAME)
Efect
Declaratia unui lock
Initializarea unui lock
Preluarea unui lock de catre un thread. Daca un alt thread a preluat lock-ul inainte, acesta va astepta pana cand thread-ul respectiv va elibera lock-ul
Eliberarea unui lock de catre un thread
Verifica daca un lock este preluat sau nu
omp_destroy_lock(&NAME)
Exemplu
int x = 0;
omp_lock_t lck;
omp_init_lock (&lck);
omp_set_lock (&lck);
#pragma omp parallel shared (x)
{
#pragma omp master
{
x = x + 1;
omp_unset_lock (&lck);
}
}
omp_destroy_lock (&lck);
4/4