我正在处理的应用程序涉及多个流程,所有流程都在处理类似的任务,并且只是偶尔共享信息。我有一个使用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应该能够继续计算。
感谢。