background image

Pro

gramowanie równoległe i współbieżne 

Ćwiczenie:  

Ćwiczenie 4

 

Data oddania: 

15.4.2013 

Imię, Nazwisko: 

Kulecka Aleksandra

 

Ocena: 

Uwagi: 
 

 
 

1. 

Cel ćwiczenia 

 

Celem  ćwiczenia  było  zapoznanie  się  z  komunikacją  punktową  w  MPI  na  podstawie  dwóch 

sposób przesyłania komunikatu (ping-pong oraz token). 

 

2. 

Kod źródłowy wraz z objaśnieniem 

#include "stdafx.h" 
#include <stdio.h> 

#include <iostream> 
#include "mpi.h" 
 

using namespace std; 
 

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

 

int rank, dest; 
int size; 

int inmsg, tag = 1; 
int rc, source; 

 
MPI_Status Stat; 
MPI_Init( 0, 0 ); 

MPI_Comm_rank(MPI_COMM_WORLD, &rank); 
MPI_Comm_size(MPI_COMM_WORLD, &size); 

 
int count = 2; 
 

if(rank == 0) 
{   dest = rank + 1; 

    source = size - 1; 
    inmsg = 0; 
    for (int i = 0; i < count; i++ ) 

    { 
        rc = MPI_Send(&inmsg,1,MPI_INT,dest,tag,MPI_COMM_WORLD); 

        cout << "Proces " << rank << " wyslano do " << dest <<" liczbe " <<inmsg <<endl; 
        inmsg += 1; 

        rc = MPI_Recv(&inmsg,1,MPI_INT,source,tag,MPI_COMM_WORLD,&Stat); 
        cout << "Proces " << rank << " odebrano od " << source <<" liczbe " <<inmsg<<endl; 
    } 

}else if(rank == (size-1)) 

    source = rank - 1; 
    dest = 0; 
    for (int i = 0; i < count; i++ ) 

    { 
        rc = MPI_Recv(&inmsg,1,MPI_INT,source,tag,MPI_COMM_WORLD,&Stat); 

background image

        cout << "Proces " << rank << " odebrano od " << source <<" liczbe " <<inmsg<<endl; 
        inmsg += 1; 
        rc = MPI_Send(&inmsg,1,MPI_INT,dest,tag,MPI_COMM_WORLD); 

        cout << "Proces " << rank << " wyslano do " << dest <<" liczbe " <<inmsg <<endl; 
    } 

}else  

    source = rank - 1; 

    dest = rank + 1; 
    for (int i = 0; i < count; i++ ) 

    { 
        rc = MPI_Recv(&inmsg,1,MPI_INT,source,tag,MPI_COMM_WORLD,&Stat); 

        cout << "Proces " << rank << " odebrano od " << source <<" liczbe " <<inmsg<<endl; 
        inmsg += 1; 
        rc = MPI_Send(&inmsg,1,MPI_INT,dest,tag,MPI_COMM_WORLD); 

        cout << "Proces " << rank << " wyslano do " << dest <<" liczbe " <<inmsg <<endl; 
         

    } 

 

MPI_Finalize(); 
return 0; 


 

 

 

Kolorem 

żółtym oznaczono fragment, w którym załączam 4 podstawowe biblioteki, służące do 

wykorzystywania charakterystycznych poleceń w programie (np. polecenie cout, cin, MPI_Send,...). 
 
Kolorem jasnozielonym oznaczono 

linijkę, dzięki której, wykorzystanie poleceń z biblioteki iostream, 

nie musi zostać poprzedzone każdorazowo odnośnikiem do klasy std (std::cout, std::cin). 
 
Błękitnym kolorem oznaczono deklarację/definicję zmiennych lokalnych, przechowujących rozmiar, 
treść, źródło, tag, cel oraz inne parametry komunikatu wysyłanego za pomocą MPI między procesami. 
 
Różowy kolor oznacza zadeklarowanie zmiennych charakterystycznych dla MPI takich jak status 
komunikatu, początek pętli przesyłania, wielkość oraz rozmiar komunikatu. 
 
Niebieski kolor oznacza deklarację i definicje zmiennej lokalnej oznaczającej ile razy komunikat będzie 
przesłany. 
 
W zależności od numeru procesu, który aktualnie jest rozpatrywany przez program (kolor czerwony) 
wykonywane jest pewne polecenie. 
 
Jeśli jest to proces początkowy (rank ==0), to zwiększony staje się numer procesu  (komunikat będzie 
wysyłany do kolejnego procesu), źródło z którego komunikat w procesie początkowym został 
odebrany, jest równy wielkości procesu - 1 (numeracja rozpoczyna się od 0! ). Następnie za 
przesyłaną wiadomość podstawia się wartość początkową równą 0. W pętli for, od 0 do licznika 
(zadeklarowanego w niebieskim oznaczeniu)

, wykonują się następujące czynności:  

 

Za 

zmienną rc podstawiony zostaje wynik funkcji MPI_Send (wiadomość wysłana), które 

przyjmuje za zmienne 

treść komunikatu do wysłania, zmienną typu MPI_INT, kierunek, do 

którego wysyła się komunikat, tag komunikatu, oraz wielkość samego procesu. 

 

N

astępnie zostaje wypisana na ekran informacja o wysłaniu komunikatu oraz jego treści, 

źródle i odbiorcy. 

 

W

iadomość zostaje zwiększona o 1. 

 

Ponownie 

za zmienną rc podstawiany jest rezultat działa funkcji MPI_Recv (wiadomość 

odebrana

), który przyjmuje następujące argumenty: odebrany komunikat,treść, zmienną typu 

MPI_INT, źródło komunikatu, tag, wielkość procesu oraz aktualny status. 

background image

 

Wyświetlona zostaje informacja o odebraniu komunikatu ze źródłem, treścią komunikatu oraz 

odborcy. 

Jeśli proces nie jest procesem początkowym, a końcowym, wówczas, za źródło przyjmuje się wielkość 
procesu - 

1 (numeracja następuje od 0!), odbiorcą (czy przeznaczeniem komunikatu) jest proces 

początkowy - 0, a następnie zostaje wykonana pętla for o dokładnie takim samym działaniu jak w 
pierwszym przyadku (odebranie wiadomości, zapisanie stanu do zmiennej, wyświetlenie informacji o 
postępie, zwiększenie komunikatu, wysłanie komunikatu, wypisanie informacji o wysłaniu). 
 
Jeśli natomiast proces znajduje się pomiędzy początkiem a końcem (i nie jest ani początkiem, ani 
końcem), wówczas za źródło podstawiana wielkość procesu - 1, za przeznaczenie wielkość  
procesu + 1, a do

piero później wykonywana jest pętla for. 

 
Polecenie 

MPI_Finalize(); zamyka pętlę przesyłania komunikatu. 

 
Polecenie 

return 0; zwraca wartość 0 z funkcji głównej main.