MPI_Send
può o non può bloccare. Bloccherà finché il mittente non potrà riutilizzare il buffer del mittente. Alcune implementazioni torneranno al chiamante quando il buffer è stato inviato a un livello di comunicazione inferiore. Alcuni altri ritorneranno al chiamante quando c'è un corrispondente MPI_Recv()
all'altra estremità. Quindi dipende dalla tua implementazione MPI se questo programma si bloccherà o meno.
A causa di questo programma si comporta in modo diverso tra le diverse implementazioni MPI, si può considerare rewritting così non ci saranno eventuali situazioni di stallo:
MPI_Comm_rank (comm, &my_rank);
if (my_rank == 0) {
MPI_Send (sendbuf, count, MPI_INT, 1, tag, comm);
MPI_Recv (recvbuf, count, MPI_INT, 1, tag, comm, &status);
} else if (my_rank == 1) {
MPI_Recv (recvbuf, count, MPI_INT, 0, tag, comm, &status);
MPI_Send (sendbuf, count, MPI_INT, 0, tag, comm);
}
sempre essere consapevoli del fatto che per ogni MPI_Send()
ci deve essere un abbinamento MPI_Recv()
, entrambi "paralleli" nel tempo. Ad esempio, questo potrebbe finire in deadlock perché l'accoppiamento di chiamate send/recv non è allineato nel tempo. Si incrociano:
RANK 0 RANK 1
---------- -------
MPI_Send() --- ---- MPI_Send() |
--- --- |
------ |
-- | TIME
------ |
--- --- |
MPI_Recv() <-- ---> MPI_Recv() v
Questi processi, al contrario, non si concluderà in stallo, purché ovviamente, che vi sono due processi con ranghi 0 e 1 nello stesso dominio comunicatore.
RANK 0 RANK 1
---------- -------
MPI_Send() ------------------> MPI_Recv() |
| TIME
|
MPI_Recv() <------------------ MPI_Send() v
Il programma sopra fisso può riuscire se la dimensione del comunicatore com
non consente rango 1 (solo 0). In questo modo, il if-else
non prenderà il percorso else
e, quindi, nessun processo sarà in ascolto per il MPI_Send()
e il grado 0 sarà deadlock.
Se è necessario utilizzare il layout di comunicazione corrente, è preferibile utilizzare MPI_Isend()
o MPI_Issend()
per le mandate non bloccanti, evitando così il deadlock.