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 1
Programmi 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 2
Operazioni 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 3
Esempio 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. 4
Message 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) 5
Message 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 6
Considerazioni 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 7
Message 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 8
Non 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 9
considerazioni PVM e MPI implementano sia operazioni bloccanti e non bloccanti Le operazioni bloccanti facilitano il programmatore Le operazioni non bloccanti migliorano le prerformance 10
Message Passing Interface MPI Un programma MPI è costituito da processi autonomi, ciascuno dei quali esegue il proprio codice nello stile MIMD 11
MPI: 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 12
Caratteristiche Comunicazioni punto-punto Comunicazioni collettive Supporto topologico Gestione degli errori MPI ha 125 funzioni 6 sono le più usate 13
Terminologia 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 14
Init 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 15
Esempio: Hello world! 16
Dominio 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 17
Comm_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 18
Esempio: Hello world 2 19
Esempio: Hello world 3 20
Hello 3 run 21
Send 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;}; 22
Corrispondenza tra i tipi di dato MPI e C 23
Gruppi 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 24
Esempio: master – slave … 25
… master – slave 26
Send&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) 27
Esempio: 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 28
Topologie 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 29
Operazioni 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 30
Riferimenti 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 31
Puoi anche leggere