openmp,openmpi basics

5
LABORATOR 1. Familiarizarea cu mediile MPI si OpenMP. 1. MPI Standardul MPI consta dintr-o specificație de funcții de biblioteca si un mediu de rulare pentru programarea paralela distribuita, bazata pe pasare de mesaje. Exista mai multe implementări MPI. In cadrul laboratorului vom lucra cu varianta OpenMPI, pachet care se regăsește in majoritatea distribuțiilor Linux. In MPI avem conceptul de ‚comunicatori’ = un grup de procese, controlate de mediul MPI, care comunica. Exista un comunicator predefinit, identificat prin MPI_COMM_WORLD. In cadrul unui comunicator, procesele sunt identificate secvențial, prin 0, 1, 2, .. n-1. In terminologia MPI, identificatorul unui proces se numește rangul (rank) acestuia. Exemplu de program folosind MPI #include <stdio.h> #include <mpi.h> int main (int argc, char**argv) { int rank, size; MPI_Init (&argc, &argv); /* initializare bibl. MPI */ MPI_Comm_rank (MPI_COMM_WORLD, &rank); /* identificatorul proc. curent */ MPI_Comm_size (MPI_COMM_WORLD, &size); /* numarul de procese */ printf( "Acesta este procesul nr. %d din %d\n", rank, size ); MPI_Finalize(); return 0; } se compileaza cu: mpic++ -o hello_mpi hello_mpi.cpp rezultatul compilarii este executabilul hello_mpi pentru o rulare distribuita, paralela, acesta se lanseaza cu ajutorul comenzii mpirun -np <numar procese> <nume program>

Upload: steven-bright

Post on 11-Nov-2015

2 views

Category:

Documents


0 download

DESCRIPTION

openMp,openMPI basics

TRANSCRIPT

  • LABORATOR 1.

    Familiarizarea cu mediile MPI si OpenMP.

    1. MPI

    Standardul MPI consta dintr-o specificaie de funcii de biblioteca si un mediu de rulare pentru

    programarea paralela distribuita, bazata pe pasare de mesaje.

    Exista mai multe implementri MPI. In cadrul laboratorului vom lucra cu varianta OpenMPI,

    pachet care se regsete in majoritatea distribuiilor Linux.

    In MPI avem conceptul de comunicatori = un grup de procese, controlate de mediul MPI, care

    comunica. Exista un comunicator predefinit, identificat prin MPI_COMM_WORLD.

    In cadrul unui comunicator, procesele sunt identificate secvenial, prin 0, 1, 2, .. n-1.

    In terminologia MPI, identificatorul unui proces se numete rangul (rank) acestuia.

    Exemplu de program folosind MPI

    #include

    #include

    int main (int argc, char**argv)

    {

    int rank, size;

    MPI_Init (&argc, &argv); /* initializare bibl. MPI */

    MPI_Comm_rank (MPI_COMM_WORLD, &rank); /* identificatorul proc. curent */

    MPI_Comm_size (MPI_COMM_WORLD, &size); /* numarul de procese */

    printf( "Acesta este procesul nr. %d din %d\n", rank, size );

    MPI_Finalize();

    return 0;

    }

    se compileaza cu:

    mpic++ -o hello_mpi hello_mpi.cpp

    rezultatul compilarii este executabilul hello_mpi

    pentru o rulare distribuita, paralela, acesta

    se lanseaza cu ajutorul comenzii mpirun -np

  • De ex:

    mpirun -np 3 ./hello_mpi

    Acesta este processul 0 of 3

    Acesta este processul 1 of 3

    Acesta este processul 2 of 3

    Note

    1.) Sistemul MPI, in functie de configuratie, poate lansa procesele in paralel pe acelasi

    calculator, sau pe mai multe calculatoare, preconfigurate.

    2.) Prin natura distribuita a programelor MPI, procesele sunt izolate, acestea comunicand

    prin canalele specificie platformei MPI. Utilizarea altor metode de comunicare nu este

    recomandata.

    2. OpenMP

    OpenMP este un set de directive de compilare pentru limbajele C/Fortran, care faciliteaz

    scrierea programelor paralele.

    Paralelismul oferit de OpenMP este prin intermediul firelor de execuie (threadurilor).

    Threadurile au acces comun la memoria globala a sistemului, nefiind necesara folosirea

    mesajelor pentru comunicare.

    De exemplu, un program similar cu cel de mai sus, dar in OpenMP este:

    #include

    #include

    #include

    int main (int argc, char *argv[]) {

    int nthreads, tid;

    // Sectiunea de mai jos va fi executata,

    // in paralel, de mai multe threaduri

    #pragma omp parallel private(nthreads, tid)

    {

    tid = omp_get_thread_num();

    printf("Acesta este threadul %d\n", tid);

    // threadul cu indentificatorul 0

    // denumit si 'master thread'

    if (tid == 0)

    {

    nthreads = omp_get_num_threads();

    printf("Numar threaduri = %d\n", nthreads);

  • }

    }

    }

    g++ -o hello_mp -fopenmp hello_mp.cpp

    Pentru rulare, se executa ./hello_mp.

    Numrul de threaduri poate fi controlat din variabila de mediu

    export OMP_NUM_THREADS=3

    $ ./hello_mp.exe

    Acesta este threadul 0

    Acesta este threadul 1

    Acesta este threadul 2

    Numar threaduri = 3

    Bariera sincronizarea proceselor prin bariere

    La apelul metodei MPI_Barrier(comm), fiecare proces apelant se blocheaza pana ce

    toate procesele din grupul comm ajung la aceasta metoda.

    - Analizati, comparati, compilati si rulati programele mp_barrier si mpi_barrier;

    Reducia paralel in MPI

    Prin intermediul funciei MPI_Reduce, procesele dintr-un grup pot combina mai multe valori

    intr-una singura (de exemplu suma).

    Astfel, daca avem valorile x0, x1, x_n-1 (fiecare proces furniznd o singura valoare),

    atunci MPI_Reduce va calcula, in paralel:

    Rezultat = (x0 # x1 # x2 # x3 # . # x_n-1)

    Operatorii # disponibili sunt (o invocare de reducie folosete un singur operator):

    MPI_MAX maximul

    MPI_MIN minimul

    MPI_SUM suma

  • MPI_PROD produsul

    MPI_LAND si logic

    MPI_BAND si pe biti

    MPI_LOR sau logic

    MPI_BOR sau pe biti

    MPI_LXOR sau exclusiv logic

    MPI_BXOR sau exclusiv pe biti

    MPI_MAXLOC valoare si indice element maximal

    MPI_MINLOC valoare si indice element minimal

    Rezultatul va fi disponibil unui singur proces - destinatarul reduciei.

    In cazul functiei MPI_AllReduce, rezultatul este distribuit tuturor proceselor din grup.

    Compilati programul mpi_reduce.

    Reducia paralela in OpenMP

    In OpenMP, directiva #pragma omp reduction(operator,var) semnalizeaz compilatorul, ca

    variabila var este destinaia unei reducii paralele prin operatorul dat.

    Dei variabila var este potenial modificat in mod concurent de mai multe threaduri, compilatorul

    mpreuna cu biblioteca OpenMP va asigura, ca la sfritul seciunii paralele, variabila var va

    conine rezultatul final corect, identic cu rezultatul care s-ar fi obinut printr-o execuie

    secveniala (exceptnd cazul numerelor in virgula flotanta unde nu este garantata

    asociativitatea operatorilor aritmetici).

    #include

    #include

    #include

    int main (int argc,char**argv) {

    int n=100;

    if (argc>1)

    n=atoi(argv[1]);

    double suma=0;

    #pragma omp parallel for reduction(+:suma)

    for (int i=1; i

  • }

    Exerciiu: modificai programul de mai sus, eliminnd directiva reduction (dar pstrnd

    #pragma omp parallel for). Comparai rezultatele obinute din mai multe rulri.

    Tema de laborator.

    Folosind exemplele de mai sus de reducie paralela, implementai att in OpenMPI cat si in MP

    calculul unor serii convergente, la alegere, de exemplu

    (sursa: wikipedia)

    Programul va avea ca parametru

    N = numarul de procese MPI / treaduri OpenMP.

    Acesta se va transmite prin metoda specifica mediului:

    MPI: folosind mpirun n N sau

    OpenMP: export OMP_NUM_THREADS=N

    De exemplu, pentru prima serie data mai sus, termenul generic este

    x_k = (-1)k/(k+1)

    procesul/threadul cu indicele k va calcula termenul de mai sus.

    Totodat, msurai timpii de execuie pentru

    N=2, 4, 8, 16, 32, 64 procese MPI sau threaduri OpenMP.

    Bibliografie

    Parallel Programming in C with MPI and OpenMP de M.J. Quinn, 2003