7
Felicia Ionescu, Valentin Pupezescu – Laborator de Calcul paralel Lucrarea 5 – ALGORITMI PARALELI SIMPLI Pentru fiecare din algoritmii din această lucrare este prezentată varianta secvențială și se dau indicații de paralelizare. Se cere să se implementeze algoritmii respectivi folosind bibliotecile Pthread, OpenMP și MPI, să se testeze execuția corectă secvențială și paralelă și să se reprezinte graficele de performanțe TP(p), S(p), E(p) (în execuția pe HPC). Parametrul p depinde de modul de programare: pentru programare prin memorie partajată (Pthread și OpenMP) p = (1, 2, 4, 8, 12, 16); pentru sisteme cu transfer de mesaje (MPI), p = (1, 2, 4, 8, 16, 32, 64); parametrul n se alege în funcție de algoritm. 5.1. Calculul sumei elementelor fiecărei linii a unei matrice Algoritmul secvențial de calcul al sumei elem. fiecărei linii a unei matrice pătrate a[n][n], cu rezultat matricea coloană c[n]: for (i = 0; i < n; i++) { c[i] = 0; for (j = 0; j < n; j++) c[i] += a[i][j]; } Timpul de execuție secvențială este: T S = n 2 = O(n 2 ). Algoritmul conține o buclă imbricată pe două niveluri: bucla exterioară este o buclă perfect paralelizabilă, cu n iterații independ. (demonstrați) bucla interioară este o buclă paralelizabilă cu dependențe între iterații Paralelizarea se face prin distribuirea echilibrată celor n iterații ale buclei exterioare la p task- uri, ceea ce înseamnă partiționarea orientată pe linii a matricelor a și c; fiecare task execută s = n / p (sau s +1) iterații în care calculează elementele partiției corespunzătoare a matricei c Se obține un algoritm adaptiv perfect paralel asemănător ca performanțe cu adunarea a două matrice (care are complexitatea tot în O(n 2 )). Se testează pentru n = (64, 256, 512, 4096, 32768). 5.2. Produsul unei matrice pătrate cu o matrice coloană Algoritmul secvențial de înmulțire a matricei pătrate a[n][n] cu matricea coloană b[n], cu rezultat matricea coloană c[n] : for (i = 0; i < n; i++){ c[i] = 0; for(j = 0; j < n; j++) c[i] += a[i][j]*b[j]; } Timpul de execuție secvențială este: T S = 2n 2 = O(n 2 ) Algoritmul conține o buclă imbricată pe două niveluri: bucla exterioară este o buclă perfect paralelizabilă, cu n iterații independente (demonstrați) bucla interioară este o buclă paralelizabilă cu dependențe între iterații Paralelizarea se face prin distribuirea echilibrată a celor n iterații ale buclei exterioare la p task- uri, ceea ce înseamnă partiționarea orientată pe linii a matricelor a și c; fiecare task execută s = n / p (sau s + 1) iterații. în care calculează elementele partiției corespunzătoare a matricei c Se obține un algoritm adaptiv perfect paralel asemănător ca performanțe cu adunarea a două matrice (care are complexitatea tot în O(n 2 )). Se testează pentru n = (64, 256, 512, 4096, 32768). 1

L5 Algoritmi Paraleli Simpli

Embed Size (px)

DESCRIPTION

CP CP Cp CP

Citation preview

  • Felicia Ionescu, Valentin Pupezescu Laborator de Calcul paralel

    Lucrarea 5 ALGORITMI PARALELI SIMPLI Pentru fiecare din algoritmii din aceast lucrare este prezentat varianta secvenial i se dau

    indicaii de paralelizare. Se cere s se implementeze algoritmii respectivi folosind bibliotecile Pthread, OpenMP i MPI, s se testeze execuia corect secvenial i paralel i s se reprezinte graficele de performane TP(p), S(p), E(p) (n execuia pe HPC). Parametrul p depinde de modul de programare: pentru programare prin memorie partajat (Pthread i OpenMP) p = (1, 2, 4, 8, 12, 16); pentru sisteme cu transfer de mesaje (MPI), p = (1, 2, 4, 8, 16, 32, 64); parametrul n se alege n funcie de algoritm.

    5.1. Calculul sumei elementelor fiecrei linii a unei matrice Algoritmul secvenial de calcul al sumei elem. fiecrei linii a unei matrice ptrate a[n][n], cu

    rezultat matricea coloan c[n]: for (i = 0; i < n; i++) { c[i] = 0; for (j = 0; j < n; j++) c[i] += a[i][j]; }

    Timpul de execuie secvenial este: TS = n2 = O(n2). Algoritmul conine o bucl imbricat pe dou niveluri:

    bucla exterioar este o bucl perfect paralelizabil, cu n iteraii independ. (demonstrai) bucla interioar este o bucl paralelizabil cu dependene ntre iteraii

    Paralelizarea se face prin distribuirea echilibrat celor n iteraii ale buclei exterioare la p task-uri, ceea ce nseamn partiionarea orientat pe linii a matricelor a i c; fiecare task execut s = n / p (sau s +1) iteraii n care calculeaz elementele partiiei corespunztoare a matricei c

    Se obine un algoritm adaptiv perfect paralel asemntor ca performane cu adunarea a dou matrice (care are complexitatea tot n O(n2)). Se testeaz pentru n = (64, 256, 512, 4096, 32768).

    5.2. Produsul unei matrice ptrate cu o matrice coloan Algoritmul secvenial de nmulire a matricei ptrate a[n][n] cu matricea coloan b[n], cu

    rezultat matricea coloan c[n] : for (i = 0; i < n; i++){ c[i] = 0; for(j = 0; j < n; j++) c[i] += a[i][j]*b[j]; }

    Timpul de execuie secvenial este: TS = 2n2 = O(n2) Algoritmul conine o bucl imbricat pe dou niveluri: bucla exterioar este o bucl perfect paralelizabil, cu n iteraii independente (demonstrai) bucla interioar este o bucl paralelizabil cu dependene ntre iteraii Paralelizarea se face prin distribuirea echilibrat a celor n iteraii ale buclei exterioare la p task-

    uri, ceea ce nseamn partiionarea orientat pe linii a matricelor a i c; fiecare task execut s = n / p (sau s + 1) iteraii. n care calculeaz elementele partiiei corespunztoare a matricei c

    Se obine un algoritm adaptiv perfect paralel asemntor ca performane cu adunarea a dou matrice (care are complexitatea tot n O(n2)). Se testeaz pentru n = (64, 256, 512, 4096, 32768).

    1

  • Lucrarea 5 Algoritmi paraleli simpli

    5.3. Produsul scalar (inner product, dot product) a doi vectori Fie vectorii a[n] i b[n]; produsul lor scalar este suma produselor elementelor corespondente (ca

    indice) ale vectorilor. Algoritmul secvenial: sum = 0; for (i = 0; i < n; i++) sum += a[i]*b[i];

    Algoritmul este similar cu o reducere paralel, cu deosebirea c se nsumeaz valorile produsului elementelor a doi vectori (nu elementele unuia singur).

    Algoritmul const dintr-o bucl simpl paralelizabil cu dependene, cu timpul de execuie secvenial TS = 2n = O(n).

    Paralelizarea se face la fel ca la reducerea paralel: se partiioneaz vectorii a i b n p partiii; se execut calculul sumelor pariale (reducerea n fiecare partiie) cu p task-uri n paralel, apoi se execut reducerea global cu excludere mutual.

    Se va obine un algoritm paralel adaptiv, asemntor ca performane cu algoritmul de reducere paralel. Se testeaz pentru n = (4096, 32768, 262144, 16777216).

    5.4. Selecia elementului maxim al unui vector Se d urmtoarea problem: fiind dat un vector de n elemente, s se gseasc elementul cu

    valoare absolut maxim (max) i poziia lui n vector (r). Acest problem este forma simplificat a operaiei de gsire a liniei pivot n algoritmul de eliminare Gaussian de rezolvare a sistemelor de ecuaii lineare. Algoritmul secvenial: max = 0; r = 0; // Initializare for (i = 0; i < n; i++) if (max < fabs(a[i])){ max = fabs(a[i][k]); r = i; }

    Algoritmul conine o bucl simpl cu dependene ntre iteraii, deoarece fiecare iteraie citete i poate s scrie n variabila partajat max.

    Timpul de execuie secvenial este TS = n = O(n) Paralelizarea se face la fel ca la reducerea paralel: bucla cu n iteraii de comparare a

    elementelor vectorului a[n] este descompus (distribuit) unui numr de p thread-uri ale unei regiuni paralele; fiecare thread memoreaz valoarea maxim local (din propria partiie) n variabila local pmax i poziia ei n variabila pr.

    Valoarea maxim global se obine n variabila partajat max prin compararea valorilor variabilelor locale pmax folosind excluderea mutual.

    Se va obine un algoritm paralel adaptiv, asemntor ca performane cu algoritmul de reducere paralel. Se testeaz pentru n = (4096, 32768, 262144, 16777216).

    5.5. Algoritmi de integrare numeric 5.5.1. Integrarea numeric a funciilor de dou variabile Integrarea numeric a unei funcii de dou variabile z = f(x,y), ntre anumite limite ale

    variabilelor x i y, prin care se calculeaz volumul cuprins ntre suprafaa reprezentat de funcie i planul Oxy, este un exemplu clasic de algoritm care se poate paraleliza foarte uor.

    2

  • Felicia Ionescu, Valentin Pupezescu Laborator de Calcul paralel

    Suprafaa din planul Oxy ntre limitele de integrare (x1, x2, y1, y2) se mparte ntr-un numr de n x n dreptunghiuri elementare, iar volumul de calculat se obine prin nsumarea volumelor tuturor paralelipipedelor dreptunghice care au baza unul dintre dreptunghiurile elementare i nlimea egal cu valoarea funciei f(x,y) n centrul dreptunghiului.

    Algoritmul secvential de calcul pentru functia dat 3 3 3 3z x y x y= + , n intervalul x1, x2, y1, y2, folosind n x n diviziuni ale volumului de calculat, este urmtorul:

    dx = (x2 x1)/n; dy = (y2 y1)/n; double functie(double x, double y){ return x*x*x+y*y*y-3*x-3*y; } vol = 0; for (i = 0; i < n; i++) { x = x1 + dx * (i + 0.5); for (j = 0; j < n; j++){ y = y1 + dy * (j + 0.5); vol += functie(x, y); } } vol = vol*dx*dy; Reprezentarea grafic a funciei date (realizat n limbajul R, aa cum este descris n lucrarea dedicat limbajului R) este urmtoarea:

    Rezultatele obinute prin integrare numeric se pot verifica cu valoarea obinut analitic [3].

    [ ] [ ]3 3

    1,2 1,23 3 4.5x y x y + =

    Executnd programul pentru diferite valori ale lui n, se observ c rezultatele obinute prin integrare numeric sunt cu att mai apropiate de rezultatul analitic cu ct numrul de intervale de integrare este mai mare:

    3

  • Lucrarea 5 Algoritmi paraleli simpli

    n 16 64 128 512 4096 vol -4.579102 -4.504944 -4.501236 -4.500077 -4.500001

    Paralelizarea acestui algoritm este asemntoare cu o reducere paralel: se realizeaz o

    partiionare unidimensional dup axa Ox a matricei dreptunghiurilor elementare, prin distribuirea iteraiilor buclei exterioare a algoritmului unui numr de p thread-uri.

    In prima etap fiecare thread va calcula un volum parial (pvol) compus dintr-un numr de n / p intervale pe axa Ox , fiecare cu cte n intervale pe axa Oy

    n a doua etap se nsumeaz aceste volume partiale n variabila vol, folosind excluderea mutual.

    Implementarea Pthread a algoritmului de integrare numeric a unei funcii de dou

    variabile. Se folosete partiionarea pe linii a matricei suprafeelor elementare. Variabilele globale i funcia thread-ului sunt urmtoarele:

    // Integration_pthread.c #include int n = 1024; // n x n : numar de intervale int p = 1; // numar thread-uri int max_rep = 1; // Numar repetari executie double vol = 0.0; pthread_mutex_t mutex; double x1 = -1; // limite de integrare double x2 = 2; double ya = -1; double yb = 2; double dx, dy; // intervalele de calcul double func(double x, double y) { return (x*x*x + y*y*y -3*x -3*y); } void *Integration (void *param){// Functia thread-ului int first, last; // limitele partitiei int i, j; int q = *(int*)param; int s = (int) n/p; int k = n%p; double x, y, pvol = 0.0; if (k == 0) { // n divizibil cu p first = q*s; last = first + s; } else if (q < k) { // primele k partitii au dimensiunea s+1 first = q*(s+1); last = first + s+1; } else { // ultimele (p-k) partitii au dimensiunea s first = q*s + k;

    4

  • Felicia Ionescu, Valentin Pupezescu Laborator de Calcul paralel last = first + s;

    5

    } for(i = first; i < last; i++) { x = x1 + dx * (i + 0.5); for (j = 0; j < n; j++) { y = ya + dy * (j + 0.5); pvol += func(x, y); } } pvol = pvol*dx*dy; pthread_mutex_lock(&mutex); vol += pvol; pthread_mutex_unlock(&mutex); return 0; } int main(int argc, char *argv[]) { // Citire si verificare parametri linie de comanda ... dx = (x2 - x1)/n; dy = (yb - ya)/n; // Alocarea datelor int *params = (int*)malloc(sizeof(int)*p); pthread_t ids = (pthread_t*)malloc(sizeof(pthread_t)*p); // Initializare mutex pthread_mutex_init(&mutex,0); // Creare thread-uri si asteptare terminarii lor ... return 0; }

    Restul operaiilor auxiliare (iniializri, scriere rezultate n fiierul Res_Integration_Pthread.txt etc.) sunt foarte asemntoare cu cele de la algoritmii precedeni.

    Se creeaz un script de execuie Exec_Integration_Pthread, se msoar performanele pe multiprocesorul (cu 16 core) hpc.intern din sistemul HPC Dell PowerEdge i se reprezint graficele TP(p), S(p), E(p) pentru p = (1,2,4,8,12,16) i n = (64, 256, 512, 4096, 32768).

    Implementarea OpenMP a algoritmului de integrare numeric a unei funcii de dou

    variabile. Se folosete partiionarea pe linii a matricei suprafeelor elementare. Partea de calcul este urmtoarea:

    double vol = 0; #pragma omp parallel num_threads(p) shared(n,x1,y1,dx,dy,vol) \ private(i,j,x,y,pvol) { pvol = 0; #pragma omp for for (i = 0; i < n; i++) { x = x1 + dx * (i + 0.5); for (j = 0; j < n; j++){ y = y1 + dy * (j + 0.5); pvol += functie(x, y); } }

  • Lucrarea 5 Algoritmi paraleli simpli

    pvol = pvol*dx*dy; #pragma omp critical { vol += pvol; } }

    Restul operaiilor auxiliare (iniializri, scriere rezultate n fiierul Res_Integration_OpenMP.txt etc.) sunt foarte asemntoare cu cele de la algoritmii precedeni.

    Se creeaz un script de execuie Exec_Integration_OpenMP, se msoar performanele pe multiprocesorul (cu 16 core) hpc.intern din sistemul HPC Dell PowerEdge i se reprezint graficele TP(p), S(p), E(p) pentru p = (1,2,4,8,12,16) i n = (64, 256, 512, 4096, 32768)

    Implementare MPI a algoritmului de integrare numeric a unei funcii de dou variabile.

    Se implementeaz algoritm de integrare numeric cu partiionare unidimensional pe linii a matricei dreptunghiurilor elementare n care este mprit domeniul de integrare n planul Oxy (x1, x2, y1, y2).

    Fiecare proces calculeza un un volum parial (pvol) compus dintr-un numr de s = n / p intervale pe axa Ox , fiecare cu cte n intervale pe axa Oy, iar n final se nsumeaz aceste volume partiale n variabila vol din procesul root, folosind functia MPI_reduce().

    Partea de implementare MPI a acestui algoritm este dat mai jos. pvol = 0; vol = 0; for (m = 0; m < s; m++) { i = rank * s + m; x = x1 + dx * (i + 0.5); for (j = 0; j < n; j++) { y = y1 + dy * (j + 0.5);

    pvol += functie(x, y); } } pvol = pvol*dx*dy; MPI_Reduce (&pvol,&vol,1, MPI_DOUBLE, MPI_SUM, root, MPI_COMM_WORLD);

    Restul operaiilor auxiliare (iniializri, scriere rezultate n fiierul Res_Integration_MPI.txt etc.) sunt foarte asemntoare cu operaiile din ceilalte programe studiate.

    Se creeaz un script de execuie Exec_Integration_MPI, se execut n clusterul HPC cu 64 procesoare, se msoar performanele i se reprezint graficele TP(p), S(p), E(p) pentru p = (1,2,4,8,12,16) i n = (64, 256, 512, 4096, 32768).

    Se observ c performantele de execuie paralel sunt foarte bune, apropiate cu cele obinute de programul OpenMP (cu pn la 16 procesoare); accelerarea este aproape de accelerarea paralel ideal (S = p, linia punctat pe graficul S(p)), eficiena este peste 0.8 pentru dimensiunea n = 32768 a grilei de divizare.

    Acest lucru se explic prin faptul c n algoritmul de integrare numeric comunicaiile ntre procesoare sunt foarte puine, numai la sfritul execuiei (pentru calculul volumului total prin operaia de reducere).

    5. 5.2. Integrarea numeric a funciilor de o variabil

    Se folosete ca exemplu algoritmul de calcul al unei aproximaii a numarului . Algoritmul secvenial calculeaz aceast aproximaie prin integrare numeric pentru a gsi aria

    mrginit de curba y = 4/(1+x2), ntre 0 i 1 dat fiind c:

    6

  • Felicia Ionescu, Valentin Pupezescu Laborator de Calcul paralel

    ===+ )04/(4))0()1((4141

    02 arctgarctgx

    dx

    Intervalul [0, 1] este mprit ntr-un numr de n subintervale de lime 1/n. Pentru fiecare subinterval, algoritmul calculeaz aria dreptunghiului a crui nlime este astfel aleas nct curba 4/(1+x2) s intersecteze latura de sus a dreptunghiului n punctul de mijloc.

    Aria dreptunghiului din pozitia i a intervalului [0, 1] are mijlocul bazei x = (i + 0.5) / n. Baza (latimea) egala dreptunghiului este egala cu 1/n si inaltimea este y(x) = 4 / (1 + x*x).

    Suma ariilor acestor dreptunghiuri aproximeaz aria mrginit de curb. Cu ct n este mai mare, cu att aproximaia este mai bun, deoarece diferena dintre suma ariilor dreptunghiurilor i aria mrginit de curb este mai mic. Algoritmul de calcul, n limbajul C, este urmatorul:

    #define n . // numar de subintervale sum = 0.0; for (i = 0; i < n; i++) { x = (i + 0.5)/n; sum += 4/(1 + x*x); } sum /= n;

    Dezvoltai versiunile Pthread, OpenMP i MPI ale acestui algoritm. Executai algoritmul, verificai rezultatul (ct de bun este aproxumarea lui n funcie de numrul de intervale de integrat n). Executai algoritmul pe HPC, msurai i reprezentai performanele acestuia pentru n = (4096, 32768, 262144, 16777216). Bibliografie Toate referinele de la lucrrile precedente

    7