Sari la conținutul principal

Despre MPI și programarea distribuită

Până acum, ați lucrat cu programarea paralelă, care presupune existența a mai multor fire de execuție (threads), care execută instrucțiuni în mod paralel și concurent, ele având acces la aceeași zonă de memorie, în cadrul unei singure mașini de calcul, care are mai multe procesoare.

Putem extinde conceptul de programare paralelă prin folosirea a mai multor mașini de calcul, care sunt conectate în cadrul unei rețele într-un concept numit programarea distribuită.

Spre deosebire de programarea paralelă, în programarea distribuită nu există conceptul de memorie partajată (shared memory). Întrebarea este următoarea: cum poate o mașină să știe ce date are o altă mașină din cadrul rețelei? Soluția este comunicarea prin mesaje, realizată de către mașinile (de tip nod) dintr-o rețea. Comunicarea prin mesaje are două funcționalități:

  • comunicarea: un nod (transmițător / sender) trimite date prin intermediul unui canal de comunicație către un alt nod (receptor / receiver)
  • sincronizarea: un mesaj nu poate fi recepționat înainte ca acesta să fie transmis

MPI (Message Passing Interface) reprezintă un standard pentru comunicarea prin mesaje, elaborat de MPI Forum, și are la bază modelul proceselor comunicante prin mesaje.

Un proces reprezintă un program aflat în execuție și se poate defini ca o unitate de bază care poate executa una sau mai multe sarcini în cadrul unui sistem de operare. Spre deosebire de thread-uri, un proces are propriul său spațiu de adrese (propria zonă de memorie) și acesta poate avea, în cadrul său, mai multe thread-uri în execuție, care partajează resursele procesului.

În cadrul lucrului în C/C++, MPI reprezintă o bibliotecă, care are funcționalitățile implementate într-un header numit mpi.h. Pentru compilare, la MPI există un compilator specific:

  • mpicc, pentru lucrul în C
  • mpic++, pentru lucrul în C++

În ambele limbaje, pentru rularea unui program MPI folosim comanda mpirun, împreună cu parametrul -np, unde precizăm numărul de procese care rulează în cadrul programului distribuit.

Exemplu:

  • compilare:
    • C: mpicc hello.c -o hello
    • C++: mpic++ hello.cpp -o hello
  • rulare: mpirun -np 4 hello - rulare cu 4 procese
atenție

Dacă încercați să rulați comanda mpirun cu un număr de procese mai mare decât numărul de core-uri fizice disponibile pe procesorul vostru, este posibil să primiți o eroare cum ca nu aveți destule sloturi libere. Puteți elimina acea eroare adăugând parametrul --oversubscribe atunci când rulați mpirun.

atenție

Instalare MPI: Pentru a lucra cu MPI, trebuie să instalați biblioteca pentru MPI pe Linux, folosind următoarea comandă:

sudo apt install openmpi-bin openmpi-common openmpi-doc libopenmpi-dev
atenție

În caz că lucrați cu MPI pe WSL, o să vă apară un warning, care poate fi fixat cu ajutorul hint-urilor de aici.