如何使用MPI组织异步通信?

3
我计划使用MPI构建一个支持异步通信的求解器。基本思路如下:
假设有两个并行进程。进程1想定期向进程2发送好的解决方案,并在需要多样化时从进程2请求好的解决方案。
以下是具体步骤:
1. 在某一时刻,进程1使用MPI_send向进程2发送一个解决方案。由于此发送是动态触发的,如何保证有一个MPI_Recv与此MPI_Send匹配呢?
2. 当进程1需要一个解决方案时,它如何向进程2发送请求,而进程2能及时注意到它的请求呢?

“保证”每个MPI_Send都有匹配的MPI_Recv的方法是构建代码,使其发生。您可以使用MPI_Barrier来同步两个进程,并在已知点上交换解集。 - Stan Graves
2个回答

4
有三种方法可以实现您想要的,尽管它们不是真正的异步通信。
1) 使用非阻塞发送/接收。将您的发送/接收调用替换为irecv/isend并等待。发送方可以发出isend并继续处理下一个问题。在某个时候,您将必须发出mpi-wait以确保您之前的发送已被接收。您的process2可以提前使用irecv发出接收请求并继续进行其工作。同样,在某个时候,您将调用mpi-wait以确保您的irecv已被接收。如果我正确理解了您的需求,这可能有点麻烦。
2) 一种优雅的方法是使用单边通信。MPI_Put、Get。
3) 重新设计算法,在某些时间间隔内,进程1和2交换信息和状态。

1
根据您调用的MPI_*函数的性质,发送将会阻塞,直到另一个进程调用匹配的接收函数,因此您需要确保在您的代码中这一点得到实现。同时,还有非阻塞函数调用MPI_Isend等,它会给您提供一个请求句柄,稍后您可以检查该句柄以查看进程的发送是否已被匹配的接收函数接收。
关于您的问题,您可以发出一个非阻塞接收(MPI_Irecv是最基本的),并根据您的应用程序每n秒检查一次状态。当消息已经被接收并准备好被读取时,状态将被设置为完成。
如果时间很敏感,请在等待消息时使用阻塞调用。然而,在OpenMPI中,阻塞机制使用旋转轮询,因此等待进程将占用100%的CPU。

谢谢您的建议。事实上,我更关心接收过程如何检测到有消息到来?需要一直使用while循环进行检查吗?是否有更好的方法? - Jackie
没问题 :) 是的,使用最简单的单发单收范式,你可以设置一个异步接收,需要自己负责检查,或者使用阻塞调用,在有新消息时立即返回。在阻塞时,OpenMPI 只会进行忙等待(占用 100% 的 CPU,以获得最佳通信性能),但 MPICH2 可以配置为阻塞并等待中断,对 CPU 更加友好。 - Alexander Sagen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接