MPI_Alltoall 比 MPI_Alltoallv 能跑多少?

Dan*_*ica 2 mpi

我想知道当传输的数据量大致相同时,执行MPI_AlltoallvMPI_Alltoall函数之间的运行时间有什么区别?我找不到任何这样的基准测试结果。我对大规模实例感兴趣,其中使用了数万个或数十万个 MPI 进程,并且这些进程对应于给定 HPC 系统的重要部分(最多考虑一些现代的,例如 BG/Q 、克雷 XC30、克雷 XE6、...)。

Jef*_*eff 5

概述

MPI_Alltoall 的一大优势是可以快速做出协议决策,因为它们依赖于少量标量。相比之下,如果库实现者想要优化 MPI_Alltoallv,他们必须扫描四个向量来确定,例如,通信是否接近同构、高度稀疏或某种其他模式。

另一个问题是 MPI_Alltoall 可以轻松地将输出缓冲区用作暂存空间,因为每个进程提供和消耗相同数量的数据。对于 MPI_Alltoallv,做所有的簿记是不切实际的,因此将分配任何暂存空间。我不记得这个问题的具体细节,但我想我已经在 MPI canon 的某个地方读过它。

实现骨架

alltoallv 至少有两种特殊情况,可以比 MPI 库优化得更好:

  1. 几乎同构的通信,即计数向量几乎是恒定的。当您的分布式阵列不能在整个流程网格中均匀分配时,就会发生这种情况。在这种情况下,您可以:

  2. 填充数组并直接使用 MPI_Alltoall。

  3. 对具有同构通信的进程子集使用 MPI_Alltoall,对其余进程使用 MPI_Alltoallv 或一批 Send-Recv。如果您可以缓存关联的通信器,则效果最佳。使用非阻塞通信也应该有所帮助。

  4. 编写您自己的 Bruck 实现来处理计数变化的情况,这可能在您的向量末尾。自己没有做过,不知道这有多么困难或值得。

  5. 稀疏通信,即计数向量包含大量零。对于这种情况,只需使用一批非阻塞的 Send-Recv 和 Waitall,因为这可能是 MPI 库所能做的最好的,并且自己做可以让您根据需要调整批量大小。

文件

百万处理器上的 MPI描述了与向量集合相关的可扩展性问题。诚然,您可能看不到在大多数 CPU 上扫描向量参数的成本,但这是一个 O(n) 问题,它促使实现者不要过多地接触向量参数。

HykSort:分布式内存架构上超立方体快速排序的新变体描述了一种自定义实现,其性能比优化库要好得多。这种优化很难在 MPI 库内部实现,因为它可能相当专业。(顺便说一下,这个参考是针对 Hristo 的评论,而不是你的问题。)

代码

通过比较 MPICH 中这些操作的实现,您可以发现一些有趣的事情(https://github.com/pmodels/mpich/blob/main/src/mpi/coll/alltoall.chttps://github.com/ pmodels/mpich/blob/main/src/mpi/coll/alltoallv.c)。只有 MPI_Alltoall 使用布鲁克算法和成对交换。类似的结论可以从可用的选项绘制I_MPI_ADJUST_ALLTOALLI_MPI_ADJUST_ALLTOALLVhttps://software.intel.com/en-us/node/528906。这些限制是基本的还是仅仅是实用的,留给读者练习。

实践经验

当 Blue Gene/P 上的 MPI_Alltoall 使用 DCMF_Alltoallv(源代码)时,因此相对于 MPI_Alltoallv 没有区别,而且后者可能更好,因为应用程序预先填充了向量参数。

我为 Blue Gene/Q 编写了一个与 MPI_Alltoall 一样快的多对多交换版本。我的版本不知道常量和向量参数,所以这个结果意味着 MPI_Alltoallv 的性能与 MPI_Alltoall 相似。但是,我现在找不到可以绝对确定细节的代码。

但是,Blue Gene 网络相当特殊,尤其是多对多网络,因此在 CPU 比网络快得多的系统上,胖树或龙网络上的行为将大不相同。

我建议您编写一个基准测试并在您打算运行应用程序的位置对其进行测量。一旦你有了一些数据,找出可能遗漏的优化就会容易得多。