background image

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

Ćwiczenie:  

Ćwiczenie 4

 

Data oddania: 

15.4.2013 

Imię, Nazwisko: 

Dawid Misiniec

 

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; 


 

 

 

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. 

 

Następnie zostaje wypisana na ekran informacja o wysłaniu komunikatu oraz jego treści, 
źródle i odbiorcy. 

 

Wiadomość 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. 

 

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 dopiero później wykonywana jest pętla for. 
 
Polecenie 

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