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
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
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
OpenMP ofron:
Model programimi Fork-Join
Multi-threaded
OpenMP konsiston ne:
Direktiva kompilatori
#pragma omp direktiva [clauses] { …........... }
Funksione librarie
omp_get_num_threads()
Variabla ambienti
export OMP_NUM_THREADS=4
Direktiva Kompilatori:
Rajonet paralele
Ndarja e punes
Sinkronizimi
Atribute te fushepamjes se te dhenave - private - firstprivate - lastprivate - shared - reduction
Funksione librarie
Numri i thread-ve
Thread ID
Ndryshimi dinamik i numrit te thread-ve
Parelelizmi i perfshire
Timers
Locking API
Variablat e ambientit
Cakton numrin e thread-ve
Tipi i skedulimit
Ndryshimi dinamik i numrit te thread-ve
Parelelizmi i perfshire
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)
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)
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)
Klauzolat e OpenMP
Shume direktiva to OpenMP permbajne klauzola
Klauzolat perdoren per te specifikuar informacione shtese per direktivat
Direktiva te caktuara kane klauzola specifike
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
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
- 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
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; }
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; }
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]); } } }
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]); } } }
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);
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
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)
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