在接收消息之前必须多次MPI_Iprobe

时间:2015-12-03 07:11:05

标签: mpi openmpi

我正在处理的应用程序涉及多个流程,所有流程都在处理类似的任务,并且只是偶尔共享信息。我有一个使用openMPI的工作实现,但是我遇到的消息问题有时会比发送时晚得多。

此时,每个进程的主循环从处理任何等待消息开始,然后执行一大堆计算,然后使用MPI_ISend将结果发送到每个其他进程。类似的东西:

while problem is unsolved:
  bool flag;
  MPI_Iprobe(MPI_ANY_SOURCE, ..., &flag, MPI_IGNORE_STATUS);
  while flag:
    MPI_Recv(&message, ...);
    // update local information based on message contents
    MPI_Iprobe(MPI_ANY_SOURCE, ..., &flag, MPI_IGNORE_STATUS);

  result = doComputation(); // between 2s and 1m

  MPI_Request request;
  for dest in other_processes:
    MPI_Isend(result, ..., dest, &request);
    MPI_Wait(&request, MPI_STATUS_IGNORE); // Doesn't seem to make any difference 

这样可以正常工作,但是经常会出现以下问题:进程X发送一条消息,但下次进程Y探测时,它找不到任何消息。通常,只有一个或两个循环(以及许多秒)以后,进程Y获取进程X发送的消息。消息最终总是通过,但进程Y不应该等到第二次或第三次它探测实际接收消息。

我对MPI的工作原理并不十分了解,但是从阅读其他问题来看,我认为问题与MPI没有机会推进消息有关,因为在我的程序中MPI功能是只是偶尔调用,而不是在紧密的循环中。试图给MPI一些额外的时间来进步,我给Iprobe添加了几个虚拟调用:

bool flag;
MPI_Iprobe(MPI_ANY_SOURCE, ..., &flag, MPI_IGNORE_STATUS);
MPI_Iprobe(MPI_ANY_SOURCE, ..., &flag, MPI_IGNORE_STATUS);
MPI_Iprobe(MPI_ANY_SOURCE, ..., &flag, MPI_IGNORE_STATUS);
MPI_Iprobe(MPI_ANY_SOURCE, ..., &flag, MPI_IGNORE_STATUS);
while flag:
  MPI_Recv(&message, ...);
  // update local information based on message contents
  MPI_Iprobe(MPI_ANY_SOURCE, ..., &flag, MPI_IGNORE_STATUS);

并且它可以工作 - 任何发送的消息总是在进程探测它们时被接收。

但这很难看,我怀疑它可能会在不同平台上产生不同的结果。那么有没有另一种方法可以让MPI在探测之前有一段时间完成消息进展?我不想在没有探测的情况下使用阻塞接收,因为当没有消息等待时,进程Y应该能够继续计算。

感谢。

0 个答案:

没有答案