【问题标题】:How much can MPI_Alltoall outperform MPI_Alltoallv?MPI_Alltoall 能胜过 MPI_Alltoallv 多少?
【发布时间】:2020-12-29 05:56:16
【问题描述】:

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

【问题讨论】:

  • 如果传输的数据量相同,为什么要使用 alltoallv?自洽 MPI 表示 alltoallv 提供了更大的灵活性,因此在任何情况下它都不应优于 alltoall —— 否则库应该简单地将 alltoall 设为 alltoallv 的一个特例。
  • 如果数据量比较大,一般用MPI_Alltoall还是MPI_Alltoallv都无所谓。当数据量相对较小时,有许多有效的算法可以实现具有相同大小的块(即MPI_Alltoall)的all-to-all。什么是“相对小”,什么是“相对大”取决于系统和网络架构。
  • @RobLatham:与 MPI_Alltoallv 相比,仅调用一次 MPI_Alltoall 无法解决我的问题。也许(我仍然不知道,必须证明)可以多次(至少两次)调用 MPI_Alltoall 来解决。
  • @HristoIliev:我不确定,因为我认为一些集体在 MPP 上进行了高度优化,但不是全部。我在某处读到 MPI_Alltoallv 通常是使用点对点操作实现的,用户的实现甚至可以比库提供的实现更好。
  • 自定义实施很少能胜过供应商的解决方案。但有时供应商太懒或太忙,无法测试所有内容。例如,大约三年前,我在 reported 的一个 Open MPI 实现中出现了性能回归 reported 以及它的补丁。尽管修复起来微不足道,但修复从未进入 1.6 或 1.7。最重要的是,该算法成为 1.6 中的默认算法,因为它可以更好地扩展(没有性能回归)。

标签: mpi


【解决方案1】:

概述

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

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

实现骨架

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

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

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

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

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

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

论文

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

HykSort: a new variant of hypercube quicksort on distributed memory architectures 描述了一个比优化库执行得更好的自定义实现。这种优化很难在 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 使用 Bruck's algorithm 和成对交换。从https://software.intel.com/en-us/node/528906 上的I_MPI_ADJUST_ALLTOALLI_MPI_ADJUST_ALLTOALLV 的可用选项可以得出类似的结论。这些限制是基本的还是仅仅是实际的,留给读者练习。

实践经验

当 Blue Gene/P 上的 MPI_Alltoall 使用 DCMF_Alltoallv (source code) 时,与 MPI_Alltoallv 没有区别,而且后者可能会更好,因为应用程序预先填充了向量参数。

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

然而,Blue Gene 网络相当特殊,尤其是 w.r.t. all-to-all,因此在 CPU 比网络快得多的系统上,fat-tree 或 dragonly 网络上的行为将完全不同。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-09
    • 1970-01-01
    • 2011-01-28
    • 1970-01-01
    • 1970-01-01
    • 2021-05-24
    • 2020-12-26
    相关资源
    最近更新 更多