我想实现一个系统,其中有一个接收器和多个发送器。每个发送者都不断向接收者发送数据。接收器等待接收数据并进行处理。这是玩具的例子。
#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>
以防止任何编译问题。
答案 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