Programmazione con il paradigma Message Passing - Cap. 6
←
→
Trascrizione del contenuto della pagina
Se il tuo browser non visualizza correttamente la pagina, ti preghiamo di leggere il contenuto della pagina quaggiù
Programmazione con il paradigma
Message Passing
Cap. 6
1Programmi per il message passing
Asincroni
I task concorrenti vengono eseguiti in modo asincrono:
Può avere un comportamento non deterministico
è estremamente difficile da leggere e capire
Debolmente asincroni
I task si sincronizzano per eseguire le interazioni
Diventa più semplice ragionare sui programmi
è prevista anche l’esecuzione di job diversi su diversi processori,
ma in questo modo i programmi non sono scalabili
La maggior parte dei programmi che fanno uso di
message passing sono scritti usando l’approccio
single program multiple data: SPMD
2Operazioni Send e receive
Nella forma più generale:
send(void *sendbuf, int nelems, int dest);
Buffer che contiene i dati Numero di dati Identificatore del
che devono essere spediti da spedire processo che riceve i
dati
receive(void *recvbuf, int nelems, int source);
Buffer che Numero di dati Identificatore del processo
memorizza i dati da ricevere da cui vengono spediti i
ricevuti dati
3Esempio Memorizzo il dato
ricevuto in a
Po P1
Uno solo
a = 100; receive(&a,1,0); Ricevuto dal
send(&a,1,1); printf(“%d\n”,a); processo 0
a=0;
Quale valore riceve
modifico il il buffer destinatario?
valore di a uno solo
La semantica dell’operazione di send
invio il dato richiede che il valore ricevuto da P1 sia 100
contenuto al processo 1
nel buffer a
Tuttavia
Se la piattaforma hw supporta l’accesso diretto alla memoria
(il dato vinene direttamente copiato da una memoria all’altra)
e il trasferimento asincrono dei messaggi,
il processo P1 potrebbe ricevere il valore 0 invece di 100
L’operazione di send deve bloccare fino a quando la semantica
dell’operazione non è garantita.
se send sblocca (permette l’esecuzione del resto del programma prima che P1
abbia ricevuto il dato) P1 può ricevere il dato sbagliato.
4Message passing bloccante non buffered
Blocking non-buffered send-receive
L’operazione di send non termina finché il processo ricevente non ha
avuto il messaggio (handsahke tra il processo mittente e destinatario che
permette l’inizio dell’operazione di trasferimento)
5Message passing bloccante con buffer
Blocking buffered send-receive
Con l’uso dei buffer, quando il processo mittente deve eseguire una send mette
il messaggio nel buffer e termina dopo che la copia nel buffer è completata.
Può continuare con le altre operazioni. I dati trasferiti vengono memorizzati in
un buffer del processo ricevente. Quando il processo destinatario incontra
un’operazione di receive verifica che i dati siano nel suo buffer
Solo il ricevente ha un buffer: i dati vengono depositati nel buffer e presi solo
quando viene invocata la receive
2 buffer Solo 1 buffer al ricevente 6Considerazioni
I protocolli che ammettono buffer non hanno tempi di
attesa
Bisogna tenere sotto controllo la quantità di dati inviati
al buffer in base alla sua capacità
C’è ancora pericolo di deadlock
Po P1
receive(&a,1,1); receive(&a,1,0);
send(&b,1,1); send(&b,1,0);
Entrambe le receive attendono che i dati inviati siano caricati nel buffer
Probelmi nel protocollo bloccante
Senza buffer – tempi d’attesa
Con buffer – gestione del buffer
7Message passing non bloccante
I protocolli non bloccanti terminano le send/receive
prima che sia assicurata la loro correttezza semantica
Sono accompagnate da un’operazione check-status
che indica se la semantica di un trasferimento
precedente è stata o non violata
una volta che la non blocking send/receive termina, il
processo è libero di continuare
Successivamente il processo controlla se l’operazione
di trasferimento è stata completata
Anche la non blocking può essere buffered o non-
buffered
8Non blocking non-buffered e buffered
•Manda una richiesta di send •Manda una richiesta di send e mette i dati
•Continua a fare altre operazioni nel buffer
•Quando il processo ricevente dà ok al send •Continua a fare altre oprazioni
vengono inviati i dati •Quando il processo ricevente dà ok al
•Il check status indica la riuscita della send vengono inviati i dati nel buffer
comunicazione • non c’è bisogno di controllare il check
status 9considerazioni
PVM e MPI implementano sia operazioni bloccanti e
non bloccanti
Le operazioni bloccanti facilitano il programmatore
Le operazioni non bloccanti migliorano le prerformance
10Message Passing Interface
MPI
Un programma MPI è costituito da processi autonomi,
ciascuno dei quali esegue il proprio codice
nello stile MIMD
11MPI: caratteristiche
Libreria di funzioni per il message passing di supporto
allo sviluppo di programmi paralleli (’92)
Non richiede hw specializzati
Asincrono / debolmente sincrono
Preferibilmente Single Program Multiple Data
Assume la memoria partizionata:
Dal punto di vista logico una macchina è composta da p processori
ognuno dei quali ha una sua memoria (memoria non condivisa) e
accede solo ai suoi dati locai e.g.: cluster
Supporta solo parallelizzazione esplicita
Svantaggi: codice poco strutturato e complesso
Vantaggi: pieno controllo da parte del programmatore – performance e
scalabilità alte
12Caratteristiche
Comunicazioni punto-punto
Comunicazioni collettive
Supporto topologico
Gestione degli errori
MPI ha 125 funzioni
6 sono le più usate
13Terminologia MPI
Tutti gli identificatori MPI, inclusi gli identificatori di
funzioni iniziano con MPI_ seguito da una lettera
maiuscola e altre minuscole
Es: MPI_Init(&argc, &argv)
Tutte le costanti MPI sono stringhe composte da
lettrere maiuscole e _ precedute sempre da MPI_
Es: MPI_COMM_WORLD
Header file per un programma C
#include
14Init e Finalize
MPI_Init MPI_Init(&argc, &argv)
Inizializza l’ambiente MPI
Deve essere chiamata prima di ogni altra funzione MPI
Non deve essere necessariamente la prima istruzione del
programma
È la prima funzione che eseguono tutti i processi
Esegue il setup del sistema che permette tutte le successive
chiamate parallele
MPI_Finalize MPI_Finalize()
È l’ultima istruzione MPI
Viene chiamata da tutti i processi
Libera la memoria allocata da MPI
15Esempio: Hello world!
16Dominio di comunicazione
Insieme di processi che possono comunicare tra loro
Le variabili del tipo MPI_Comm memorizzano i domini di
comunicazione communicators
I comunicatori devono essere specificati in ogni istruzione di
trasferimento di messaggi
Identificano in modo univoco i processi che partecipano alle
operazioni di trasferimento
Un processo può appartenere a differenti domini di comunicazione
MPI_COMMON_WORLD è una costante che include tutti i processi
coinvolti nell’esecuzione parallela
Se c’ è un solo gruppo di comunicatori coincide con
MPI_COMMON_WORLD
17Comm_size e Common_rank
int MPI_Comm_size(MPI_Comm comm, int *size)
Restituisce nella variabile size il numero di processi
del communicator domain comm
Se si chiama
MPI_Comm_size(MPI_COMM_WORLD,&size)
Quando c’ è un singolo processo per processore in
size viene restituito il numero di processori usati dal
programma
rank il rango di un processo è un intero che identifica
il processo (0 … n. processi-1)
int MPI_Comm_rank(MPI_Comm comm, int *rank)
Il comunicatore comm assegna al processo il suo rank
18Esempio: Hello world 2
19Esempio: Hello world 3
20Hello 3 run
21Send e receive
int MPI_Send (void *buf, int count, MPI_datatype
datatype, int dest, int tag, MPI_Comm comm)
int MPI_Recv (void *buf, int count, MPI_datatype
datatype, int source, int tag, MPI_Comm
comm, MPI_Status *status)
buf punta al buffer che contiene il messaggio da inviare/ricevere;
count numero di elelmenti del tipo MPI_datatype contenuti nel buffer;
datatype tipo di dato supportato da MPI;
dest/source numero del processo destinatario/ricevente del
messaggio che appartiene al dominio di comunicazione comm;
tag valore intero associato al messaggio [0…32767];
comm dominio di comunicazione;
status struttura dati che contiene informazioni sull’esito
dell’operazione receive:
Typedef struct MPI_Status
{ int MPI_SOURCE; int MPI_TAG; int MPI_ERROR;};
22Corrispondenza tra i tipi di dato MPI e C
23Gruppi di comunicatori
MPI_Comm_split ( MPI_Comm comm, int color, int key,
MPI_Comm *newcomm)
Viene chiamata da tutti I processi del dominio
Partiziona il gruppo di processi in sottogruppi disgiunti in base a
color
All’interno di ogni sottogruppo (newcomm) i processi vengono
rinumerati
24Esempio: master – slave …
25… master – slave
26Send&receive
Int MPI_Sendrecv(
void *sendbuf,
int sendcount,
MPI_Datatype senddatatype,
int dest,
ind sendtag,
void *recvbuf,
int recvcount,
MPI_Datatype recvdatatype,
int source,
int recvtag,
MPI_comm comm,
MPI_Status status)
27Esempio: odd-even sort
Input: un array di lunghezza n (random), p processi
Output: l’array ordinato in ordine crescente
Algoritmo parallelo:
Si determinano p processi (n multiplo di p)
si generano p sotto-array (random) cisacuno di n/p elementi
Si ordinano gli p array con un algoritmo di oridnamento (e.g.
quick-sort)
Si esegue un ciclo in cui le coppie contigue (e disgiunte) di
array oridnati vengono fuse e divise nuovamente in due array,
alternando le coppie i,i+1 e i-1,i ad ogni ciclo di calcolo
Dopo p-1 iterazioni i sotto-array, se presi in sequenza, danno
luogo all’array ordinato
Esempio:
n=18, p=6
9,7,1 5,4,5 10,3,8 9,1,4 2,6,5 8,0,3
28Topologie virtuali per i processi
Modo conveniente per identificare un processo all’interno di un
gruppo. Per default si ha un ranking dei processi lineare (0..k-1).
Spesso conviene organizzarei processi secondo pattern 2-3dim.
Topologia cartesiana
int MPI_Cart_create(…,
int ndims, numero di dimensioni della topologia
int *dims, array: lunghezza di ogni dimensione
int *periods, periods[i]!=0 non ci sono wraparound
…)
Ogni processo è identificato dalle sue coordinate nella topologia
…. il processo coord(i,j)
MPI_Cart_rank n. del processo a partire dalle sue coordinate
MPI_Cart_coord coordinate del processo a partire dal suo rank
29Operazioni di comunicazione collettive
Sincronizzazione
MPI_Barrier sincronizza tutti i processi di un gruppo: termina
solo dopo che tutti i processi del gruppo l’hanno chiamamta
Broadcast
MPI_Bcast
Riduzioni
MPI_Reduce
30Riferimenti
Manuale MPI in linea
http://www.mpi-forum.org/docs/mpi-11-html/mpi-
report.html
Implementazione open source per MPI: LAM/MPI
http://www.lam-mpi.org
OcamlMPI: interfaccia con MPI
http://paulliac.inira.fr/~xleroy/software.html
31Puoi anche leggere