MPI_Isend MPI_recv丢失数据

时间:2012-11-08 14:17:47

标签: c++ mpi

MPI_Recv是否可能收到标签不匹配的消息?

我的逻辑:MPI_Isend / MPI_Recv通讯。

节点1 Isend带有标签0的消息,然后Isend另一条带有标签1的消息,因为节点1中有两个线程,因此Isend动作可能同时发生。
节点2将探测是否有来自节点1的消息,如果是,则接收该消息。

在我的设计中,我希望节点2接收带有标签0的消息,然后标记1.但是当节点2探测到消息来自节点1的信号时,它收到的消息长度与节点1相同。标记1消息。然后没有来自节点1的消息。似乎标签0消息丢失了。

我很困惑,期待一些答案。

2 个答案:

答案 0 :(得分:2)

MPI不能丢失消息,除非它们以“就绪”模式发送,即使用MPI_RsendMPI_Irsend,而接收方尚未就绪,这显然不是你的情况。 MPI_Isend启动发送操作,但除非进度完成,否则无法保证完成。许多MPI调用导致非阻塞操作正在进行,但最明确的操作是MPI_Wait及其变体。还有MPI实现具有特殊的进程线程,可以在后台进行非阻塞操作(例如,Open MPI可以通过这种方式编译)。

如果第二个消息非常小并且正在使用不同的发送模式(例如一些急切的发送协议),则第二个消息可能在第一个消息之前到达。 MPI仅保证具有相同信封的消息按顺序保留。消息信封是元组(发送者,接收者,标签,通信者)。

你也谈到从不同的线程发送消息。您确定您的MPI库是线程安全的,并且您使用MPI_THREAD_MULTIPLE级别的线程支持对其进行了初始化,例如:

int provided;

MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided);
if (provided != MPI_THREAD_MULTIPLE)
{
   printf("Sorry, your MPI library does not provide MPI_THREAD_MULTIPLE\n");
   MPI_Abort(MPI_COMM_WORLD, 0);
}

答案 1 :(得分:0)

您最好的选择是让接收方为标记0发布MPI_IRecv,然后为标记1发布MPI_IRecv。然后等待,直到消息使用MPI_Wait*进入,这可能是MPI_WaitAllMPI_WaitAnyMPI_Wait取决于接下来需要发生的事情。

通过这种方式,你有两个接听电话正在等待消息,标记的消息就会到达应该去的地方。

相关问题