background image

9. MPI. Definicja standardu

9. MPI. Definicja standardu

Cz

Cz

ęść

ęść

I

I

Lesław Sieniawski © 2010

background image

Specyfikacja standardu MPI

Specyfikacja standardu MPI

Opracowany przez MPI Forum

(40+ organizacji, w tym dostawcy, naukowcy, twórcy 
bibliotek oprogramowania, u

Ŝ

ytkownicy)

Nie b

ę

d

ą

c oficjalnym standardem ISO ani 

IEEE

, praktyczny, przeno

ś

ny, efektywny, elastyczny

uznany jako 

de facto standard

do tworzenia 

aplikacji obliczeniowych z przekazywaniem 
komunikatów

Specyfikacja interfejsu

dla C/C++ i Fortranu

background image

Geneza MPI

Geneza MPI

d

ło

h

tt

p

s:

//

co

m

p

u

ti

n

g

.l

ln

l.

g

o

v

/t

u

to

ri

a

ls

/m

p

i/

 ]

background image

W

W

ł

ł

a

a

ś

ś

ciwo

ciwo

ś

ś

ci MPI

ci MPI

Standaryzacja

dost

ę

pno

ść

praktycznie na 

wszystkich platformach

Przeno

ś

no

ść

– brak konieczno

ś

ci modyfikacji kodu 

ź

ródłowego po przeniesieniu na inn

ą

platform

ę

zgodn

ą

ze standardem MPI

Implementacje dla konkretnych platform

mog

ą

wykorzystywa

ć

ich specyficzne cechy dla 

zwi

ę

kszania wydajno

ś

ci

Funkcjonalno

ść

– MPI-1 dostarcza 115 procedur

Dost

ę

pno

ść

– ró

Ŝ

norodno

ść

implementacji 

komercyjnych i public domain

background image

MPI 

MPI 

model programowania

model programowania

Wsparcie:

praktycznie dla ka

Ŝ

dego modelu 

programowania równoległego z rozproszon

ą

pami

ę

ci

ą

tj. MIMD (SPMD)

Platformy sprz

ę

towe

:

– Z pami

ę

ci

ą

rozproszon

ą

(cel wyj

ś

ciowy)

– Z pami

ęć

współdzielon

ą

(w tym SMP, NUMA)

– Hybrydowe

(masowe maszyny równoległe, klastry SMP, 

klastry stacji roboczych, sieci heterogeniczne)

Równoległo

ść

jawna

, obsługiwana przez programist

ę

Stała liczba podzada

ń

(

task

realizuj

ą

cych równoległe 

zadanie (

job

). 

Brak mo

Ŝ

liwo

ś

ci dynamicznego tworzenia 

podzada

ń

(dotyczy MPI-1)

background image

MPI 

MPI 

sk

sk

ł

ł

adniki API

adniki API

Biblioteki funkcji i plików nagłówkowych

– J

ę

zyka C

– J

ę

zyka C++

– J

ę

zyka Fortran 77

– J

ę

zyka Fortran 90

Ś

rodowisko uruchomieniowe

(runtime

analogicznie do apletów j

ę

zyka Java

background image

MPI 

MPI 

podstawowe obiekty

podstawowe obiekty

Komunikator

– Okre

ś

la kontekst komunikacji: zbiór procesów które mog

ą

si

ę

ze sob

ą

komunikowa

ć

– Predefiniowany komunikator 

MPI_COMM_WORLD

obejmuj

ą

cy 

wszystkie procesy MPI

– Programista mo

Ŝ

e definiowa

ć

nowe komunikatory

Grupa 

kolekcja komunikuj

ą

cych si

ę

procesów

Identyfikator procesu w komunikatorze

tzw. 

rank

– liczba całkowita, nieujemna (0, 1, …) nadana 

przez system w chwili inicjalizacji procesu

– u

Ŝ

ywany do wskazywania nadawców i odbiorców 

komunikatów i do adresowania wykonawców czynno

ś

ci 

w zadaniu

background image

Komunikacja punkt

Komunikacja punkt

-

-

punkt

punkt

Zasady 

– Przekazywanie komunikatów pomi

ę

dzy dwoma (!) 

podzadaniami MPI (nadawca – odbiorca)

– 

Ŝ

ne typy procedur:

Synchroniczne wysyłanie

Blokuj

ą

ce wysyłanie / blokuj

ą

ce odbieranie

Nieblokuj

ą

ce wysyłanie / nieblokuj

ą

ce odbieranie

Buforowane wysyłanie 

Kombinowane wysyłanie / odbieranie

– Dozwolone ł

ą

czenie ró

Ŝ

nych typów procedur wysyłania i 

odbierania

– Dodatkowe procedury obsługi 

(np. czekanie na komunikat, 

badanie czy komunikat ju

Ŝ

nadszedł)

background image

Komunikacja punkt

Komunikacja punkt

-

-

punkt (2)

punkt (2)

Buforowanie

konieczno

ść

obsługi komunikacji przy braku 

synchronizacji podzada

ń

, np. 

– Nadej

ś

cia komunikatu przed uzyskaniem gotowo

ś

ci odbiorcy 

do przyj

ę

cia go

– Równoczesnego nadej

ś

cia wielu komunikatów do odbiorcy 

zdolnego tylko do pojedynczego ich przyjmowania

Konieczno

ść

ustalenia, co zrobi

ć

z komunikatami, które nie 

mog

ą

by

ć

odebrane w chwili nadej

ś

cia - zadanie 

rozwi

ą

zywane poprzez

bufor systemowy 

(składnik 

implementacji MPI) lub

bufor aplikacyjny 

(składnik standardu 

MPI)

background image

Komunikacja punkt

Komunikacja punkt

-

-

punkt . Bufor systemowy

punkt . Bufor systemowy

[ na podstawie: 

https://

https://

computing.llnl.gov

computing.llnl.gov

/

/

tutorials

tutorials

/

/

mpi

mpi

/

/

]

]

Send

Wykonawca 1

Aplikacja

Dane

Bufor
systemowy

Sie

ć

komputerowa

Sie

ć

komputerowa

Recv

Wykonawca 2

Aplikacja

Dane

Bufor

systemowy

Dane

background image

Komunikacja punkt

Komunikacja punkt

-

-

punkt. Bufor systemowy (2)

punkt. Bufor systemowy (2)

Cechy bufora systemowego

– Nieprzezroczysto

ść

dla programisty

– Niewystarczaj

ą

ce udokumentowanie

– Ograniczona pojemno

ść

– Niekiedy niedost

ę

pno

ść

tam, gdzie 

wymagany

– Zdolno

ść

poprawiania wydajno

ś

ci programu 

przez umo

Ŝ

liwienie komunikacji asynchro-

nicznej

background image

Komunikacja punkt

Komunikacja punkt

-

-

punkt. Bufor aplikacyjny

punkt. Bufor aplikacyjny

Bufor aplikacyjny

= przestrze

ń

adresowa zarz

ą

dzana przez programist

ę

(zmienne programowe)

Bufor wysyłania zapewniony przez MPI

background image

Tryby blokowania/

Tryby blokowania/

nieblokowania

nieblokowania

Z blokowaniem

Procedura wysyłaj

ą

ca (

send

) ko

ń

czy prac

ę

, kiedy jest 

gwarancja, 

Ŝ

e modyfikacja danych w buforze nadawczym nie 

zmieni danych przeznaczonych dla odbiorcy; w tym celu dane 
nie musz

ą

by

ć

ju

Ŝ

odebrane przez adresata 

– Synchroniczne wysyłanie z blokowaniem

zastosowanie tzw. handshakingu

– Asynchroniczne wysyłanie z blokowaniem

wykorzystanie bufora systemowego

Procedura blokowanego odbioru (

recv

) ko

ń

czy prac

ę

gdy dane nadeszły i s

ą

gotowe do wykorzystania 

przez program

background image

Tryby blokowania/

Tryby blokowania/

nieblokowania

nieblokowania

(2)

(2)

Bez blokowania

Procedury nieblokuj

ą

cego wysyłania i nieblokuj

ą

cego odbioru 

ko

ń

cz

ą

prac

ę

bez czekania na efekty komunikacji,

Moment wyst

ą

pienia zdarzenia dotycz

ą

cego realizowanej 

komunikacji nie jest przewidywalny

Modyfikacja bufora aplikacyjnego przed upewnieniem si

ę

Ŝ

nieblokuj

ą

ca operacja została uko

ń

czona jest niebezpieczna; 

wskazane jest wykorzystanie odpowiedniej procedury czekania

Komunikacja nieblokuj

ą

ca słu

Ŝ

y głównie do nakładania w czasie 

oblicze

ń

i komunikacji oraz zwi

ę

kszania wydajno

ś

ci

background image

Tryby blokowania/

Tryby blokowania/

nieblokowania

nieblokowania

(3)

(3)

Wi

ę

kszo

ść

procedur komunikacyjnych punkt-punkt 

działa w obydwu trybach

background image

Porz

Porz

ą

ą

dek i sprawiedliwo

dek i sprawiedliwo

ść

ść

Porz

ą

dek

– Gwarancja braku wyprzedzania si

ę

przez komunikaty

– Reguły kolejno

ś

ci nie obowi

ą

zuj

ą

przy wykorzystywaniu do 

komunikacji mechanizmu wielow

ą

tkowo

ś

ci 

Sprawiedliwo

ść

– Brak gwarancji sprawiedliwo

ś

ci,

– Programista musi zabezpieczy

ć

program przed zagłodzeniem 

operacji, np. 

podzadanie A wysyła komunikat do podzadania B, 

podzadanie B ma przygotowan

ą

odpowied

ź

dla A, 

w tym czasie podzadanie C wysyła komunikat do B i odbiera 
st

ą

d odpowied

ź

przeznaczon

ą

dla A 

A nie dostaje odpowiedzi od B

background image

MPI 

MPI 

struktura programu

struktura programu

#include <mpi.h>

Inne dyrektywy, deklaracje i prototypy

Pocz

ą

tek programu

Kod sekwencyjny

Inicjalizacja 

ś

rodowiska MPI = pocz

ą

tek kodu równoległego

Obliczenia i komunikacja

Zako

ń

czenie pracy 

ś

rodowiska MPI = koniec kodu równoległego

Kod sekwencyjny

Koniec programu

background image

MPI 

MPI 

Format wywo

Format wywo

ł

ł

ania procedury

ania procedury

Posta

ć

ogólna:

rc = MPI_Xxxx(parametr,…);

rc –

kod powrotu (ang. return code)

Po poprawnym wykonaniu procedury

rc = MPI_SUCCESS

(predefiniowana stała)

background image

MPI 

MPI 

Procedury wymiany 

Procedury wymiany 

komunikat

komunikat

ó

ó

w

w

Przeznaczenie

– Wymiana danych mi

ę

dzy procesami

– Wysyłanie komunikatów kontrolnych

– Synchronizacja procesów

Wła

ś

ciwo

ś

ci

– Niezale

Ŝ

no

ść

od platformy

kolejno

ść

przesyłania bajtów dla 

standardowych typów danych

Dodatkowe funkcje dla typów niestandardowych

– Adresowanie komunikatów

do konkretnych 

background image

MPI 

MPI 

Procedury wymiany komunikat

Procedury wymiany komunikat

ó

ó

w (2)

w (2)

Rozsyłanie komunikatów

– Ukrywanie szczegółów realizacyjnych

– Automatyzacja doboru schematu przepływu danych

Przykład: Badamy czas potrzebny procesowi #1 do wysłania tego samego 

komunikatu do procesów #2 – #8. 

Wariant podstawowy

(7 komunikatów)

Wariant ulepszony

(4 komunikaty)

Wariant optymalny

(3 komunikaty)

[r

y

s

u

n

k

i:

 h

tt

p

:/

/w

w

w

-u

s

e

rs

.m

a

t.

u

n

i.

to

ru

n

.p

l/

~

b

a

la

/s

e

m

_

m

g

r_

2

0

0

0

/m

p

i.

h

tm

l]

background image

MPI 

MPI 

Procedury zarz

Procedury zarz

ą

ą

dzania

dzania

ś

ś

rodowiskiem wykonawczym

rodowiskiem wykonawczym

Przeznaczenie

Inicjalizacja i ko

ń

czenie działania 

ś

rodowiska MPI

Badanie wła

ś

ciwo

ś

ci 

ś

rodowiska

Sprawdzanie to

Ŝ

samo

ś

ci

Kontrola poprawno

ś

ci przesyłania komunikatów

inne

background image

MPI 

MPI 

Procedury zarz

Procedury zarz

ą

ą

dzania

dzania

ś

ś

rodowiskiem wykonawczym (2)

rodowiskiem wykonawczym (2)

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

jednorazowa inicjalizacja 

ś

rodowiska MPI w tym utworzenie 

domy

ś

lnego komunikatora 

MPI_COMM_WORLD; 

konieczne 

wywołanie przed pierwszym wywołaniem jakiejkolwiek innej 

procedury MPI 

int MPI_Comm_size(MPI_Comm comm,int *size)

ustalenie liczby procesów w grupie zwi

ą

zanej z komunikatorem

int MPI_Comm_rank(MPI_Comm comm,int *rank)

okre

ś

lenie identyfikatora wywołuj

ą

cego procesu w obr

ę

bie 

komunikatora; pocz

ą

tkowo ka

Ŝ

dy proces ma swój ID w obr

ę

bie 

komunikatora globalnego

MPI_COMM_WORLD

(tzw. identyfikator 

podzadania). W razie zwi

ą

zania si

ę

z innymi komunikatorami, 

proces posiada w ka

Ŝ

dym z nich odr

ę

bny unikalny ID

background image

MPI 

MPI 

Procedury zarz

Procedury zarz

ą

ą

dzania

dzania

ś

ś

rodowiskiem wykonawczym (3)

rodowiskiem wykonawczym (3)

int MPI_Abort(MPI_Comm comm,int error_code)

zako

ń

czenie wszystkich procesów MPI zwi

ą

zanych ze 

wskazanym komunikatorem (w wi

ę

kszo

ś

ci implementacji zamyka 

wszystkie

procesy, bez wzgl

ę

du na podany komunikator)

int MPI_Get_Processor_name(char *name, 

int *name_length)

zwrócenie nazwy wykonawcy i jej długo

ś

ci; bufor nazwy musi 

pomie

ś

ci

ć

co najmniej 

MPI_MAX_PROCESSOR_NAME

znaków; 

rezultat zale

Ŝ

ny od implementacji (np. nazwa hosta)

int MPI_Initialized(int *flag)

zwrócenie 

true

, je

ś

li wcze

ś

niej wywołano 

MPI_Init

lub 

false

w przeciwnym przypadku; ułatwia to konstruowanie zło

Ŝ

onych 

struktur, bo ka

Ŝ

dy proces musi wywoła

ć

MPI_Init

dokładnie 

jeden raz

background image

MPI 

MPI 

Procedury zarz

Procedury zarz

ą

ą

dzania

dzania

ś

ś

rodowiskiem wykonawczym (4)

rodowiskiem wykonawczym (4)

double MPI_Wtime (void)

zwrócenie czasu astronomicznego w [s] (typ 

double

)

double MPI_Wtick (void)

zwrócenie rozdzielczo

ś

ci zegara 

MPI_Wtime

w [s]

int MPI_Finalize (void)

zako

ń

czenie działania 

ś

rodowiska wykonawczego 

MPI; ostatnie wywołanie procedury MPI w ka

Ŝ

dym 

programie korzystaj

ą

cym z MPI

background image

MPI 

MPI 

Podstawowe procedury komunikacji

Podstawowe procedury komunikacji

int MPI_Send(void *buf, int count, 
MPI_Datatype datatype, int dest, int tag, 
MPI_Comm comm)

Blokuj

ą

ce wysłanie komunikatu typu 

datatype

zawartego w zmiennej 

*buf

i oznaczonego 

znacznikiem (etykiet

ą

tag

do procesu o numerze 

dest.

Typ komunikatu

– predefiniowany (

MPI_INT

,

MPI_FLOAT

,

MPI_CHAR

, itp.) lub zdefiniowany przez 

u

Ŝ

ytkownika

Znacznik (etykieta)

– liczba z zakresu 

[0..MPI_TAG_UB] 

– dodatkowe oznaczenie typu komunikatu 
wykorzystywane przez 

MPI_Recv

background image

MPI 

MPI 

Podstawowe procedury komunikacji (2)

Podstawowe procedury komunikacji (2)

int MPI_Recv(void *buf, int count, 
MPI_Datatype datatype, int srce, int
tag, MPI_Comm comm, MPI_Status
*status)

blokuj

ą

ce odczytanie z kolejki komunikatora 

comm

pierwszego komunikatu typu 

datatype

od procesu 

srce

, posiadaj

ą

cego znacznik 

tag

oraz umieszczenie 

komunikatu w 

buf

i kodu wyniku operacji w 

status

source=MPI_ANY SOURCE 

odczytanie 1. 

komunikatu od dowolnego nadawcy

tag=MPI_ANY_TAG

ignorowanie znacznika

background image

MPI 

MPI 

Podstawowe procedury komunikacji (3)

Podstawowe procedury komunikacji (3)

Bufor 

status

typu 

MPI_Status

jest tablic

ą

struktur zło

Ŝ

onych z 3 pól typu int: 

– MPI_SOURCE, 

– MPI_TAG, 

– MPI_STATUS

Bufor musi by

ć

uprzednio zadeklarowany. Zawiera 

informacje o 

ź

ródle i typie ka

Ŝ

dego odebranego 

komunikatu

background image

MPI 

MPI 

Podstawowe procedury komunikacji (4)

Podstawowe procedury komunikacji (4)

int MPI_Get_count(MPI_Status *status, 

MPI_Datatype datatype, int *count)

Ustalenie liczby odebranych komunikatów 

typu 

datatype

na podstawie zawarto

ś

ci 

zmiennej 

status

i umieszczenie wyniku 

w zmiennej 

count

background image

Kompilacja program

Kompilacja program

ó

ó

w

w

Zamiast zwykłego wywołania   

gcc plik.c –o plik opcja…

stosujemy

mpicc plik.c –o plik opcja…

Wymagania:

Ś

cie

Ŝ

ka do katalogu 

bin

z plikami wykonywalnymi 

MPI umieszczona w zmiennej 

ś

rodowiska (powłoki) 

PATH

background image

Uruchamianie program

Uruchamianie program

ó

ó

w

w

Zamiast polecenia 

./

plik

parametr_wywołania…

stosujemy

mpirun –n liczba_wykonawców \

--mca btl tcp,self

plik

\

parametr_wywołania…

background image

Uruchamianie program

Uruchamianie program

ó

ó

w (2)

w (2)

Wymagania

:

– U

Ŝ

ytkownik posiada konto

na wszystkich komputerach 

wykorzystywanych do wykonywania programu

– We wszystkich komputerach, w katalogu prywatnym 

u

Ŝ

ytkownika znajduje si

ę

kopia pliku programu

postaci wykonywalnej (np. dzi

ę

ki współdzieleniu 

jednego katalogu w sieci przez NFS lub tp.)

Korzy

ś

ci wynikaj

ą

ce ze sposobu uruchamiania

– Uniezale

Ŝ

nienie programu od sposobu jego 

wykonywania; Bez rekompilacji mo

Ŝ

na u

Ŝ

y

ć

tego 

samego programu na klastrze komputerów i na 
pojedynczej maszynie SMP

background image

#include <mpi.h> 

#include <stdio.h> 

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

{ int numtasks, rank, rc; 

rc = 

MPI_Init(&argc,&argv);

if (rc != MPI_SUCCESS) 

{ printf ("Error starting MPI program.   

Terminating.\n"); 

MPI_Abort(MPI_COMM_WORLD, rc);

MPI_Comm_size(MPI_COMM_WORLD,&numtasks); 

MPI_Comm_rank(MPI_COMM_WORLD,&rank); 

printf ("Number of tasks= %d My rank= %d\n", 

numtasks,rank); 

/******* 

do some work

*******/ 

MPI_Finalize();

Przyk

Przyk

ł

ł

ad 

ad 

-

-

program MPI  #1  [wg: https://

program MPI  #1  [wg: https://

computing.llnl.gov

computing.llnl.gov

/

/

tutorials

tutorials

/

/

mpi

mpi

/]

/]

Badanie wyniku inicjalizacji

background image

Wszystkie zademonstrowane do tej pory 

przykłady wykonano na maszynie o 
architekturze SMP (tj. wieloprocesorowej  
z pami

ę

ci

ą

współdzielon

ą

)

background image

[root@p205 openMPI]# mpicc mpi1.c -o mpi1

[root@p205 openMPI]# mpirun -n 1 --mca btl \

tcp,self mpi1

Number of tasks= 1 My rank= 0

[root@p205 openMPI]# mpirun -n 2 --mca btl \

tcp,self mpi1

Number of tasks= 2 My rank= 0

Number of tasks= 2 My rank= 1

[root@p205 openMPI]# 

Przyk

Przyk

ł

ł

ad 

ad 

-

-

program MPI  #1 

program MPI  #1 

kompilacja i uruchomienie

kompilacja i uruchomienie

background image

#include <mpi.h>

#include <stdio.h>

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

{

char nazwa_proc[256];

int

nazwa_proc_len, id;

MPI_Init(&argc, &argv);

MPI_Comm_rank(MPI_COMM_WORLD, &id);

printf("--------------------\nTu wykonawca nr %d\n", id);

printf("Wartosc stalej MPI_MAX_PROCESSOR_NAME = %d\n", 

MPI_MAX_PROCESSOR_NAME);

MPI_Get_processor_name(nazwa_proc, &nazwa_proc_len);

printf("Nazwa procesora = %s, dlugosc nazwy = %d\n", 

nazwa_proc, nazwa_proc_len);

printf("Czas aktualny = %f [s], rozdzielczosc zegara = %f 

[s]\n", MPI_Wtime(), MPI_Wtick());

MPI_Finalize();

return 0;

}

Przyk

Przyk

ł

ł

ad 

ad 

-

-

program MPI #2 

program MPI #2 

dane 

dane 

ś

ś

rodowiska wykonawczego

rodowiska wykonawczego

background image

[root@p205 openMPI]# mpicc mpi2.c -o mpi2

[root@p205 openMPI]# mpirun -n 2 --mca btl tcp,self \

mpi2

--------------------

Tu wykonawca nr 0

Wartosc stalej MPI_MAX_PROCESSOR_NAME = 256

Nazwa procesora = p205, dlugosc nazwy = 4

--------------------

Tu wykonawca nr 1

Wartosc stalej MPI_MAX_PROCESSOR_NAME = 256

Czas aktualny = 1270674511.641517 [s], rozdzielczosc

zegara = 0.000001 [s]

Nazwa procesora = p205, dlugosc nazwy = 4

Czas aktualny = 1270674511.641643 [s], rozdzielczosc

zegara = 0.000001 [s]

Przyk

Przyk

ł

ł

ad 

ad 

-

-

program MPI  #2 

program MPI  #2 

kompilacja i uruchomienie

kompilacja i uruchomienie

background image

Przyk

Przyk

ł

ł

ad 

ad 

-

-

program MPI  #3  

program MPI  #3  

[wg: 

[wg: 

http://

http://

www

www

-

-

users.mat.uni.torun.pl

users.mat.uni.torun.pl

/~

/~

bala

bala

/sem_mgr_2000/

/sem_mgr_2000/

mpi.html

mpi.html

]

]

#include <stdio.h> 

#include "mpi.h" 

main(int argc, char **argv) 

{  int my_rank; 

int p; 

int source; 

int dest; 

int tag=50; 

char message[100]; 

MPI_Status status; 

MPI_Init(&argc, &argv); 

MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); 

MPI_Comm_size(MPI_COMM_WORLD, &p); 

if (my_rank != 0) 

{ sprintf(message, "Hello from process %d.", my_rank); 

dest = 0; 

MPI_Send(message, strlen(message)+1, MPI_CHAR, dest, tag, 

MPI_COMM_WORLD); 

} else

for (source=1; source<p; source++) 

{ MPI_Recv(message, 100, MPI_CHAR, source, tag, MPI_COMM_WORLD, 

&status); 

printf("%s\n", message); 

MPI_Finalize(); 

background image

[root@p205 programy.c]# mpicc MPI-helloW.c -o MPI-helloW

[root@p205 programy.c]# mpirun -n 1 --mca btl tcp,self \

MPI-helloW

[root@p205 programy.c]# mpirun -n 2 --mca btl tcp,self \

MPI-helloW

Hello from process 1.

[root@p205 programy.c]# mpirun -n 4 --mca btl tcp,self \

MPI-helloW

Hello from process 1.

Hello from process 2.

Hello from process 3.

[root@p205 programy.c]# 

Przyk

Przyk

ł

ł

ad 

ad 

-

-

program MPI  #3 

program MPI  #3 

kompilacja i uruchomienie

kompilacja i uruchomienie

Dla 1 wykonawcy nie ma wymiany komunikatów