我有许多进程(大约100到1000),每个进程都必须向其他进程的某些(比如大约10个)发送一些数据. (通常情况下,但如果A发送给B,B也发送给A,则不一定必要.)每个进程都知道它必须从哪个进程接
所以我可以使用MPI_Alltoallv,其中许多或大部分消息长度为零.
但是,我听说出于性能原因,最好使用多个MPI_send和MPI_recv通信而不是全局MPI_Alltoallv.
我不明白:如果一系列发送和接收呼叫比一个Alltoallv呼叫更有效,为什么Alltoallv不仅仅被实现为一系列发送和接收?
对我(以及其他人)来说,只使用一次全局调用会更方便.此外,我可能不得不担心没有遇到几个Send和Recv的死锁情况(可以通过一些奇偶策略或更复杂的解决方案?或者使用缓冲的send / recv?).
你是否同意MPI_Alltoallv必须慢于10 MPI_Send和MPI_Recv;如果是,为什么和多少?
通常,对于集合体的默认建议是相反的:尽可能使用集合操作而不是编写自己的集合操作. MPI库有关通信模式的信息越多,内部优化的机会就越多.除非有特殊的硬件支持,否则集体调用实际上是在发送和接收方面内部实现的.但实际的通信模式可能不仅仅是一系列发送和接收.例如,使用树来广播一条数据可能比将相同的级别发送给一堆接收器更快.很多工作都用于优化集体沟通,很难做得更好.
话虽如此,MPI_Alltoallv有些不同.在MPI级别对所有不规则通信场景进行优化可能很困难,因此可以想象一些自定义通信代码可以做得更好.例如,MPI_Alltoallv的实现可能正在同步:它可能要求所有进程“签入”,即使它们必须发送0长度的消息.我认为这样的实现不太可能,但是here is one in the wild.
所以真正的答案是“它取决于”.如果MPI_Alltoallv的库实现与任务不匹配,则自定义通信代码将获胜.但在走这条路之前,检查MPI-3邻居集体是否适合您的问题.