MPI_Ssend和MPI_Recv的意外行为

时间:2013-07-11 14:05:06

标签: c++ mpi

我在这个小代码示例中发现了MPI中的一些意外行为(使用C ++):

int rank, size;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);

if(rank == 1) {
    int *sendDone = (int*)malloc(sizeof(int));    
    *sendDone = 1;
    MPI_Ssend(sendDone,1,MPI_INT, 0, 1,MPI_COMM_WORLD);  
    foo();    
} else {
    int *rcvDone = (int*)malloc(sizeof(int));
    bar();
    while(*rcvDone != 1) {
        MPI_Recv(rcvDone,1,MPI_INT, MPI_ANY_SOURCE, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
    }
    cout << *rcvDone << endl;
}
MPI_Finalize();

使用以下命令编译和运行它:

mpic++ sim.cc -o sim
mpirun -n 2 ./sim

守则应按以下顺序执行:

bar();
foo();

因为在执行 bar()之后,进程#0开始接收。但实际上, foo()有时会在 bar()完成之前启动。有人可以向我解释并解决问题吗?

1 个答案:

答案 0 :(得分:2)

  1. 您还没有说过如何检查首先调用哪个函数。在屏幕上创建一些东西并不能保证显示消息的正确顺序(至少在使用MPI时)。

  2. 您不需要将MPI_Recv置于循环中,因为它是阻塞函数。当你没有为* rcvDone分配起始值时,它甚至都没有推荐。

  3. 将malloc与一些MPI功能一起使用是不安全的。阅读http://www.mcs.anl.gov/research/projects/mpi/www/www3/MPI_Ssend.html

  4. 上的“线程和中断安全”部分