MPI:MPI_recv与MPI_ANY_SOURCE无法从某些进程接收消息

时间:2016-02-04 06:12:29

标签: c++ mpi openmpi

我想实现一个系统,其中有一个接收器和多个发送器。每个发送者都不断向接收者发送数据。接收器等待接收数据并进行处理。这是玩具的例子。

#include <iostream>
#include <cstdlib>
#include <mpi.h>
using namespace std;

int main(int argc, char *argv[]) {
    int _mpi_numWorkers, _mpi_rank;

    // Initialize openMPI
    MPI_Init(&argc, &argv);

    MPI_Comm_size(MPI_COMM_WORLD, &_mpi_numWorkers);
    MPI_Comm_rank(MPI_COMM_WORLD, &_mpi_rank);

    MPI_Barrier(MPI_COMM_WORLD);

    float *send_data = (float *)malloc(360 * 5000 * sizeof(float));
    MPI_Status receive_status;

    if (_mpi_rank == 0) {
        while (1) {
            MPI_Recv(send_data, 360 * 5000, MPI_FLOAT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &receive_status);

            cout << "Receive from " << receive_status.MPI_SOURCE << endl;
        }
    } else {

        while (1){
            MPI_Send(send_data, 360 * 5000, MPI_FLOAT, 0, 0, MPI_COMM_WORLD);

            //sleep(1);
        }
    }

    // Terminate
    MPI_Finalize();
    return 0;
}

问题是MPI_recv只能接收来自最多两个进程的消息,无论我设置它运行多少个进程(没有睡眠时)。我已经在一台机器和多台机器上测试了这段代码:

单机案例

我通过以下命令运行此代码:

mpiexec -n 5 ./test_mpi

然后,接收者只接收等级为1和2的发送者。

多机箱

我在5台同质物理机器上运行4个发送器和1个接收器。它们都连接到100Mbps交换机。在这种情况下,接收器也只接收来自发送者子集的数据。我使用tcpdump检查数据包,并观察一些发件人甚至不发送消息。 (这些发件人在MPI_send被阻止,但没有tcp序列增加,也没有重新传输。)

对于这两种情况,如果我让每个发送者休眠一段时间(降低发送速率),接收者可以从更多发送者接收数据。

有人可以帮我理解为什么会这样吗?

环境

使用openmpi-1.6进行Debian测试

编辑2/4/16

我在代码中包含<cstdlib>以防止任何编译问题。

1 个答案:

答案 0 :(得分:1)

MPI在这方面没有公平保证,例如。

http://www.mcs.anl.gov/research/projects/mpi/tutorial/gropp/node92.html#Node92

这意味着从MPI的角度来看,你所看到的完全是“合法的”。在我给出的链接中有一页,有一个片段可以帮助解决这个问题。简而言之,您必须手动为每个可能的发件人发出(异步)接收,然后以对您来说“公平”的方式处理它们。

http://www.mcs.anl.gov/research/projects/mpi/tutorial/gropp/node93.html#Node93