24
Cfare eshte OpenMP ? Open specifications for Multi-Processing” API(Application Programming Interface) per zhvillimin e applikimeve paralel ne C/C++, Fortran ne arkitektura me memorie te ndare (shared memory) I thjeshte per programim & paralelizem inkremental

Hyrje openmp

  • Upload
    l-dr

  • View
    236

  • Download
    6

Embed Size (px)

Citation preview

Page 1: Hyrje openmp

Cfare eshte OpenMP ?

“Open specifications for Multi-Processing”

API(Application Programming Interface) per zhvillimin e applikimeve paralel ne C/C++, Fortran ne arkitektura me memorie te ndare (shared memory)

I thjeshte per programim & paralelizem inkremental

Page 2: Hyrje openmp

OpenMP ofron:

Model programimi Fork-Join

Multi-threaded

Page 3: Hyrje openmp

OpenMP konsiston ne:

Direktiva kompilatori

#pragma omp direktiva [clauses] { …........... }

Funksione librarie

omp_get_num_threads()

Variabla ambienti

export OMP_NUM_THREADS=4

Page 4: Hyrje openmp

Direktiva Kompilatori:

Rajonet paralele

Ndarja e punes

Sinkronizimi

Atribute te fushepamjes se te dhenave - private - firstprivate - lastprivate - shared - reduction

Page 5: Hyrje openmp

Funksione librarie

Numri i thread-ve

Thread ID

Ndryshimi dinamik i numrit te thread-ve

Parelelizmi i perfshire

Timers

Locking API

Page 6: Hyrje openmp

Variablat e ambientit

Cakton numrin e thread-ve

Tipi i skedulimit

Ndryshimi dinamik i numrit te thread-ve

Parelelizmi i perfshire

Page 7: Hyrje openmp

Rajonet Paralele

Rajoni paralel eshte nje bllok kodi qe ekzekutohet nga disa thread njekohesisht

#pragma omp parallel [klauzole[[,] klauzole] ...]

{

"ky instruksion do te ekzekutohet paralelisht"

} (barrier)

Page 8: Hyrje openmp

Ushtrim: Hello World (serial)

#include <stdio.h>

void main() {

int ID = 0; printf(“Hello World (%d) \n“,ID); }

Kompilimi:

gcc Hello.c -o Hello

Output:

Hello World (0)

Page 9: Hyrje openmp

Ushtrim: Hello World (paralel)

#include <stdio.h>#include <omp.h>

void main() {

#pragma omp parallel { int ID = 0; ID= omp_get_thread_num(); printf(“Hello World (%d) \n“,ID); } }

Direktiva kompilatori teOpenMP

Funksion librariei OpenMP

Kompilimi:

gcc -fopenmp Hello.c -o Hello

Output:

Hello World (2)Hello World (1)Hello World (3)Hello World (0)

Page 10: Hyrje openmp

Klauzolat e OpenMP

Shume direktiva to OpenMP permbajne klauzola

Klauzolat perdoren per te specifikuar informacione shtese per direktivat

Direktiva te caktuara kane klauzola specifike

Page 11: Hyrje openmp

Klauzolat if/private/shared if (exp)

- Kodi ekzekutohet ne paralel n.q.s.e exp vleresohet ne “true” perndryshe ekzekutohet ne serial

private (list)

- Gjithe referencat jane per objektin lokal

- Vlerat jane te papercaktuara ne hyrje dhe dalje te rajonit paralel

shared (list)

- Te dhenat aksesohen nga te gjithe thread-et

Page 12: Hyrje openmp

Fushpamja e variablave (scoping):

Private ose te ndare (shared) - Variablat private mund te aksesohen vetem nga thread-i qe i zoteron ato - Variablat a ndare mund te aksesohen nga cdo thread

Klauzolat: privat(....)/shared(.....)/default(private|none) #pragma omp parallel #pragma omp parallel private(a,c) #pragma omp parallel default(private), shared(a,b) #pragma omp parallel default(none), shared(a,b,c)

Page 13: Hyrje openmp

Shembuj me fushpamje variablash :

int x=1;#pragma omp parallel shared(x) num_threads(2) { x++; printf(“%d\n”,x); } printf(“%d\n”,x);

int x=1; #pragma omp parallel private(x) num_threads(2) { x++; printf(“%d\n”,x); } printf(“%d\n”,x);

323

233

printon cdo gje

ne fund printon 1

Page 14: Hyrje openmp

Konstruktet e ndarjes se punes direktiva - for #pragma omp for { for(i=0;i<N;i++) a[i]=a[i]+1; }

direktiva - sections #pragma omp sections {

#pragma omp section { …code section1 } #pragma omp section { …code section2 } }

direktiva - single

#pragma omp single { .... }

Puna (kodi) ndahet ndermjet thread-ave

- keto direktiva duhet te perfshihen brenda rajoneve paralele

- barrier e nenkuptuar (implicite) ne dalje

- konstruktet e ndarjes se punes nuk krijone thread-e te reja

Page 15: Hyrje openmp

Direktiva - for

#pragma omp for [clause …]

Sherben per paralelizimin e ciklit for

int a[N],i; …... #pragma omp parallel { …..... #pragma omp for for(i=0;i<N;i++) a[i]=a[i]+1; }

Page 16: Hyrje openmp

Direktiva - for

#pragma omp for [clause …]

Sherben per paralelizimin e ciklit for

int a[N],i; …... #pragma omp parallel { …..... #pragma omp for jo cdo loop for mund te paralelizohet for(i=0;i<N;i++) duhet te kemi pavaresi te iteracioneve a[i]=a[i]+1; for(i=1;i<N;i++) a[i]=a[i-1]+1; }

Page 17: Hyrje openmp

Ushtrim: mbledhje vektoresh#include <omp.h>#define N 10int main(void) { float a[N], b[N], c[N]; int i, TID, nthreads; omp_set_num_threads(4); #pragma omp parallel default(none), private(i), shared(a,b) { #pragma omp for for (i = 0; i < N; i++) { a[i] = (i+1) * 1.0; b[i] = (i+1) * 2.0; } } #pragma omp parallel default(none), private(i,TID), shared(a,b,c,nthreads) { TID = omp_get_thread_num(); if (TID == 0) { nthreads = omp_get_num_threads(); printf("Number of threads = (%d) \n",nthreads); } printf("Thread %d starting \n",TID); #pragma omp for for (i = 0; i < N; i++) { c[i] = a[i] + b[i]; printf("%d, %d, %f, %f, %f \n",TID,i+1,a[i], b[i],c[i]); } } }

Page 18: Hyrje openmp

Ushtrim: mbledhje vektoresh#include <omp.h>#define N 10int main(void) { float a[N], b[N], c[N]; int i, TID, nthreads; omp_set_num_threads(4); #pragma omp parallel default(none), private(i), shared(a,b) { #pragma omp for for (i = 0; i < N; i++) { a[i] = (i+1) * 1.0; b[i] = (i+1) * 2.0; } } #pragma omp parallel default(none), private(i,TID), shared(a,b,c,nthreads) { TID = omp_get_thread_num(); if (TID == 0) { nthreads = omp_get_num_threads(); printf("Number of threads = (%d) \n",nthreads); } printf("Thread %d starting \n",TID); #pragma omp for for (i = 0; i < N; i++) { c[i] = a[i] + b[i]; printf("%d, %d, %f, %f, %f \n",TID,i+1,a[i], b[i],c[i]); } } }

Thread 2 starting 2, 7, 7.000000, 14.000000, 21.000000 2, 8, 8.000000, 16.000000, 24.000000 2, 9, 9.000000, 18.000000, 27.000000 Number of threads = (4) Thread 0 starting 0, 1, 1.000000, 2.000000, 3.000000 0, 2, 2.000000, 4.000000, 6.000000 0, 3, 3.000000, 6.000000, 9.000000 Thread 3 starting 3, 10, 10.000000, 20.000000, 30.000000 Thread 1 starting 1, 4, 4.000000, 8.000000, 12.000000 1, 5, 5.000000, 10.000000, 15.000000 1, 6, 6.000000, 12.000000, 18.000000

Page 19: Hyrje openmp

Paralelizimi i cikleve forHapat e pergjithshem qe duhen ndjekur

- gjej ciklet for me intensive nga ana llogaritese

- konverto keto ne cikle me iteracione te pavarur

- vendos direktiven e duhur OpenMP ne pozicionin e duhur

int i, j, A[MAX];

j = 5;for (i=0;i< MAX; i++) { j +=2; A[i] = big(j);}

int i, A[MAX];

#pragma omp parallel forfor (i=0;i< MAX; i++) { int j =5+2*i; A[i] = big(j);}

Page 20: Hyrje openmp

Klauzola reduction reduction ( operator : list )

Variabli ku aplikohet kjo direktive duhet te jete i deklaruar shared

Perdoret kur vlera e variablit akumulohet brenda nje cikli for (operatoret : +, *, -, /, &, ^, |, &&, ||) Nje kopje e variablit krijohet e inicializohet per cdo thread

Ne perfundim te rajonit ose konstruktit , applikohet opeatori mbi te gjithe variablat private te threade-ve dhe rezultati ruhet ne variablin a ndare (shared)

…... int a[n],b[n],results; …..initialization of a,b ….......... #pragma omp parallel for default(shared) private(i) reduction(+:result) { for (i=0; i < n; i++) result = result + (a[i] * b[i]); } printf("Final result= %f\n",result);

Page 21: Hyrje openmp

Klauzola Schedule (ne direktiven for) Kjo direktive percakton si ndahen iteracionet e ciklit for ndermjet thread-ve

schedule(static [,chunk])- i ndan iteracionet ne bloqe me permase “chunk” dhe ai cakton

threadeve ne kohen e kompilimit

schedule(dynamic[,chunk])– c'do thread-i i caktohet ne kohen e ekzekutimi nje bllok me permase

“chunk” nga nje “queue” kur thread perfundon bllokun e caktuar terheq nje blook tjeter nga “queue”

schedule(guided[,chunk])– Njesoj si “dynamic” vetem se permasa e blloqeve zvogelohet me

vazhdimin e perpunimit te blloqeve

schedule(runtime)– tipi i skedulimit dhe “chunk” merren nga variabli i ambientit

OMP_SCHEDULE

Page 22: Hyrje openmp

Direktiva sinkronizimi

OpenMP ofron disa mekanizma sinkronizimi

- barrier (sinkronizon gjithe thread-at ne nje pozicion te kodit)

- master (vetem thread (master) kryesor ekzekuton bllokun)

- critical (vetem nje thread ne kohe ekzekuton bllokun)

- atomic (njesoj si critical por vetem per nje variabel)

Page 23: Hyrje openmp

Shembuj sinkronizimiint x=1;

#pragma omp parallel num_threads(2){ #pragma omp master { x++; } foo(x);}

foo(1),foo(2)

int x=1;

#pragma omp parallel num_threads(2){ x++; #pragma omp barrier foo(x);} foo(3),foo(3)

foo(2),foo(2)

int x=1;

#pragma omp parallel num_threads(2){ #pragma omp critical { x++; foo(x); }}

foo(2),foo(3)

Page 24: Hyrje openmp

Ushtrimea)nderto nje program qe llogarit shumezimin scalar te dy vektoreve(dot product) ne OpenMP duke mos perdorur klauzolen reduce dhe me pas duke e perdorur ate

b) Shkruaj fillimisht nje program serial ne C qe gjen dhe shfaq ne ekran maximumin e nje vektori me numer te madh elementesh (~10000)

- Programin me siper paralelizojeni ne disa thread-e me OpenMP dhe masni sa eshte speedup-i (perfitimi

ne kohe ne krahasim me versionin serial)- Perdorni funksionet e librarise per matjen e kohes

c) shkruaj nje program serial dhe pastaj ne paralel qe gjen dhe shfaq maximumin a elementeve te dy matricave