共享内存的 MPI 与 openMP

Posted

技术标签:

【中文标题】共享内存的 MPI 与 openMP【英文标题】:MPI vs openMP for a shared memory 【发布时间】:2012-07-05 03:08:20 【问题描述】:

假设有一台计算机有 4 个 CPU,每个 CPU 有 2 个内核,所以总共有 8 个内核。以我有限的理解,我认为在这种情况下所有处理器共享相同的内存。现在,是直接使用 openMP 更好还是使用 MPI 使其通用,以便代码可以在分布式和共享设置上工作。另外,如果我将 MPI 用于共享设置,与 openMP 相比,性能会下降吗?

【问题讨论】:

哪个更好取决于您对该计划的未来计划。不过,OpenMP 要简单得多。 正如所说的,这个问题没有建设性;按照 SO 的标准,“更好”太主观了,无法得到好的答案。 【参考方案1】:

您是否需要或想要 MPI 或 OpenMP(或两者)在很大程度上取决于您正在运行的应用程序的类型,以及您的问题主要是内存限制还是 CPU 限制(或两者兼而有之)。此外,这取决于您运行的硬件类型。几个例子:

示例 1

您需要并行化,因为您的内存不足,例如您有一个模拟,并且问题太大,以至于您的数据不再适合单个节点的内存。但是,您对数据执行的操作相当快,因此您不需要更多的计算能力。

在这种情况下,您可能希望使用 MPI 并在每个节点上启动一个 MPI 进程,从而最大限度地利用可用内存,同时将通信限制在最低限度。

示例 2

您通常拥有较小的数据集,并且只想加快计算量很大的应用程序。此外,您不想花太多时间考虑并行化,而是更多地考虑一般的算法。

在这种情况下,OpenMP 是您的首选。您只需要在这里和那里添加一些语句(例如,在您想要加速的 for 循环前面),如果您的程序不太复杂,OpenMP 会自动为您完成其余的工作。

示例 3

你想要这一切。您需要更多内存,即更多计算节点,但您还希望尽可能加快计算速度,即每个节点在多个核心上运行。

现在您的硬件开始发挥作用了。根据我的个人经验,如果每个节点只有几个内核 (4-8),则使用 OpenMP 的一般开销(即启动 OpenMP 线程等)造成的性能损失超过处理器内部的开销MPI 通信(即在实际共享内存且不需要 MPI 进行通信的进程之间发送 MPI 消息)。 但是,如果您正在使用每个节点具有更多内核 (16+) 的机器,则有必要使用 混合 方法,即同时与 MPI 和 OpenMP 并行化。在这种情况下,混合并行化将是充分利用您的计算资源所必需的,但它也是最难编码和维护的。

总结 如果您遇到的问题小到只能在一个节点上运行,请使用 OpenMP。如果您知道需要多个节点(因此肯定需要 MPI),但您更喜欢代码可读性/工作量而不是性能,请仅使用 MPI。如果仅使用 MPI 不能为您提供您想要/要求的加速,您必须全部完成并采用混合方式。

关于您的第二个问题(以防不清楚): 如果您的设置完全不需要 MPI(因为您将始终只在一个节点上运行),请使用 OpenMP,因为它会更快。但是,如果您知道无论如何您都需要 MPI,我会从那个开始,然后在您知道您已经用尽所有合理的 MPI 优化选项时才添加 OpenMP。

【讨论】:

@Michael Schlottke:亲爱的 Michael,您能否向我解释一下为什么混合解决方案比仅 MPI 的解决方案更快,用于两个或多个节点的用例,每个节点都有 16 个以上的 CPU?在这种情况下使用 MPI-only 有什么缺点?非常感谢 @neil_mccauley 根据个人经验(并查看其他研究小组的示例),大多数科学代码在尝试充分利用众核节点时使用混合方法。尤其是在支持硬件线程的情况下,在节点(甚至核心)内在一定程度上使用线程级并行性似乎是有意义的。拥有极端数量的 MPI 等级会增加通信,使集体操作成本更高,并且(可以说是最重要的)增加内存消耗。在您的情况下是否有意义,只能在每台机器的每个代码的基础上回答。 @MichaelSchlottke 我有一个程序可以完成许多独立的计算任务。我已经在每个任务中实现了 OpenMP 循环级并行化。但是,加速比远不及理论加速,很大程度上取决于循环的长度。记忆对我来说不是限制。在我的代码中,只有在任务完成后才需要通信,这需要几分钟才能完成。对于我的用例,您认为仅 MPI 解决方案(在节点核心之间分配任务)会比混合方法更有效吗?非常感谢! @neil_mccauley:这取决于。如果你的计算任务真的是独立的并且不需要太多的通信,那么似乎值得尝试 MPI 并行。如果您只需要每隔几分钟进行一次通信,它应该或多或少地线性(完美地)扩展,您也不必实现那么多。但是,如果您已经使用 OpenMP 完成了循环级并行化,为什么要删除它呢?只需检查使用两者是否可以更快(尽管在您的情况下似乎不是那样)。 @MichaelSchlottke:我的计算任务是松耦合的(它是一种进化算法)。我想使用 OpenMP 删除细粒度并行化的原因是“节省” CPU 内核,因为它在我的情况下根本无法很好地扩展。我宁愿将这些内核与 MPI 一起使用。我也在考虑使用 OpenMP 并行化这些任务。在共享内存环境中会比 MPI 更好吗?【参考方案2】:

现在大多数分布式内存平台都由 SMP 或 NUMA 节点组成,不使用 OpenMP 是没有意义的。 OpenMP MPI可以完美地协同工作; OpenMP 为每个节点上的内核提供数据,而 MPI 在节点之间进行通信。这称为混合编程。它在 10 年前被认为是异国情调,但现在它已成为高性能计算的主流。

至于问题本身,鉴于所提供的信息,正确答案始终相同:IT DEPENDS

【讨论】:

【参考方案3】:

要在这样的单个共享内存机器上使用,我建议使用 OpenMP。它使问题的某些方面变得更简单,并且可能更快。

如果您打算迁移到分布式内存机器,请使用 MPI。它可以帮助您解决同样的问题两次。

我说 OpenMP 可能更快的原因是因为 MPI 的良好实现可能足够聪明,可以发现它正在共享内存环境中使用并相应地优化其行为。

【讨论】:

【参考方案4】:

从更大的角度来看,混合编程已经变得流行,因为 OpenMP 通过使用相同的地址空间从缓存拓扑中受益。由于 MPI 可能会在内存中复制相同的数据(因为进程无法共享数据),因此它可能会遭受缓存取消的影响。

另一方面,如果您正确划分数据,并且每个处理器都有一个私有缓存,那么您的问题可能完全适合缓存。在这种情况下,您将获得超线性加速。

通过谈论缓存,最近的处理器上有非常不同的缓存拓扑,并且总是:IT DEPENDS...

【讨论】:

值得注意的是,从 MPI-3 开始,进程确实可以共享数据。

以上是关于共享内存的 MPI 与 openMP的主要内容,如果未能解决你的问题,请参考以下文章

openacc 与 openmp 和 mpi 的区别?

OpenMP的简单使用教程

在 UMA 机器上使用 MPI 的优势

我可以将 MPI 与共享内存一起使用吗

OpenMp实现并行化

openMP多线程编程