Using MPI, a message appears to have been recieved

2019-01-20 19:11发布

问题:

In my test program below I am sending a message from one process to another. The trace printfs seem to indicate what the message is being received before it is sent, why is this so?

#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
/* Run with two processes */
void main(int argc, char *argv[]) {
    int rank, i, count;
    float data[100],value[200];
    MPI_Status status;   
    MPI_Init(&argc,&argv);
    MPI_Comm_rank(MPI_COMM_WORLD,&rank);
    printf("before if:%d\n",rank);
    if(rank==1) {
        printf("in if:%d\n",rank);
        for(i=0;i<100;++i) data[i]=i;
        MPI_Send(data,100,MPI_FLOAT,0,55,MPI_COMM_WORLD);
    } else {
        printf("else:%d\n",rank);
        MPI_Recv(value,200,MPI_FLOAT,MPI_ANY_SOURCE,55,MPI_COMM_WORLD,&status);
        printf("P:%d Got data from processor %d \n",rank, status.MPI_SOURCE);
        MPI_Get_count(&status,MPI_FLOAT,&count);
        printf("P:%d Got %d elements \n",rank,count);
        printf("P:%d value[5]=%f \n",rank,value[5]);
    }
    MPI_Finalize();
}

/for running the program for 8 processes i got the following result. how could process 0 recieve before process 1 sends/

- RESULT:

-before if:4\n
-before if:8\n
-else:8\n
-before if:0\n
-else:0\n
-P:0 Got data from processor 1\n 
-P:0 Got 100 elements \n
-P:0 value[5]=5.000000 \n
-before if:1\n
-in if:1\n
-before if:2\n
-else:2\n
-before if:5\n
-else:5\n
-before if:6\n
-else:6\n
-before if:7\n
-else:7\n  -before if:9\n  -else:9\n  -else:4\n  -before if:3\n  -else:3\n
*/

回答1:

The problem here isn't that you've broken the causality of time, just that MPI makes no guarantees about the order of printing messages to the screen (see MPI - Printing in an order for more details).

MPI forwards all of your stdout and stderr back to the process that called mpiexec/mpirun before printing it to the screen (since that's where the user is connected. Those messages coming from all of the different processes can arrive in any order so you may be seeing one line saying a message was received before you get another line saying the message has been sent. The messages are still occurring in the right order, they're just getting delayed in the communication channels along the way.



回答2:

How can you be so sure process 0 received the message before it was sent, I would consider it far more likely that the printf was buffered or delayed.

Printf is not guaranteed to be instant, in order to make it more responsive. Run this at the start of your code to prevent output buffering with printf:

setbuf(stdout, NULL);