OpenMPI 的收集如何工作?

How does OpenMPI's gather work?

我是 MPI 的新手,我正在尝试了解 MPI(特别是 OpenMPI)的工作原理,以便推断我的系统性能。

我试图在网上查找资源以帮助我更好地理解事物,但运气不佳。我以为我会来这里。

现在我的问题很简单:如果我有 3 个节点(1 个主节点,2 个客户端)并且我发出 MPI_Gather,根进程是顺序处理传入数据还是同时处理传入数据?换句话说,如果进程 1 第一个与进程 0 建立连接,那么进程 2 是否必须等到进程 1 发送完数据才能开始发送数据?

谢谢!

Open MPI 中有多个组件实现集体操作,其中一些组件为每个操作的实现提供多种算法。

您最有可能感兴趣的是 coll 框架的 tuned 组件,因为这是 Open MPI 默认使用的组件。 tuned 使用点对点操作实现所有集合,并提供了几种收集算法:

  • 与同步线性相关 - 当消息大到中等大小时使用
  • 二项式 - 当进程数很大或消息大小很小时使用
  • 基本线性 - 用于所有其他情况

每个算法的性能在很大程度上取决于消息大小和等级数的特定组合,因此该库带有一组试探法,试图根据数据大小和队列的大小来确定最佳算法。通讯器(如上所述)。有几种机制可以覆盖启发式方法,或者强制执行某种算法,或者提供自定义算法选择规则列表。

基本线性算法只是让根循环遍历所有其他等级,按顺序接收它们的消息。在这种情况下,等级 2 将无法在等级 1 之前发送其块,因为根将首先从等级 1 接收消息,然后才移动到等级 2。

线性同步算法将块分成两部分。就像在基本线性算法中一样,按顺序收集第一部分。第二部分是使用非阻塞接收异步收集的。

二项式算法将排名排列为二项式树。树节点处的进程从较低级别接收块,并将它们聚合成较大的块,然后传递给较高级别,直到它们到达根级别。

您可以在 Open MPI source treeompi/mca/coll/tuned 文件夹中找到 tuned 模块的源代码。在开发分支中,部分 tuned 组件被提升为集体框架的基础实现,而收集的代码将在 ompi/mca/coll/base 中找到。

Hristo 的回答当然很好,但我想提供一个不同的观点。

出乎你的意料,问题并不简单。正如 Hristo 指出的那样,在不了解更多系统细节的情况下甚至不可能具体回答它。这并不意味着问题无效,但您应该开始在不同层面上对性能进行推理。

首先,考虑收集操作的复杂性:到根的总网络传输以及内存需求随着通信器中进程的数量线性增长。这自然会限制可扩展性。

其次,您可能会假设您的 MPI 实现确实以尽可能最有效的方式实现了 MPI_Gather - 比您手工完成的要好。这个假设很可能是错误的,但它是编写程序的最佳起点。

现在当你有了你的程序时,你应该衡量并看看时间花在了哪里——或者浪费了。为此你应该 MPI performance analysis tools。现在,如果您已经确定您的 Gather 对性能有重大影响,您可以继续并尝试优化它:但是要这样做,首先考虑您是否可以在概念上更好地构建您的沟通,例如通过以某种方式一起删除计算或使用巧妙的减少来代替。如果您仍然需要坚持收集:继续并调整您的 MPI 实现。之后验证您的优化确实提高了特定系统的性能。