MPI和openMP在共享内存中的区别

28

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


1
什么更好取决于您对程序的未来计划。然而,OpenMP要简单得多。 - Fred Foo
1
这个问题的措辞不够明确,"更好"这个词太主观了,按照SO的标准来看,它无法得到好的答案。 - High Performance Mark
4个回答

59
无论你需要还是想要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。


1
@Michael Schlottke:亲爱的Michael,你能否解释一下为什么混合解决方案在每个节点拥有16个或更多CPU的情况下,比MPI-only方案更快?在这种情况下使用MPI-only的缺点是什么?非常感谢。 - neil_mccauley
3
从个人经验和其他研究团队的例子来看,大多数科学代码在尝试充分利用众核节点时使用混合方法。特别是支持硬件线程时,在单个节点(甚至核心)内使用线程级并行性似乎是有意义的。拥有极高数量的MPI进程会增加通信量,使集体操作更加昂贵,而且(可能最重要的是)会增加内存消耗。是否适用于您的情况,只能基于每个代码和每台机器进行回答。 - Michael Schlottke-Lakemper
@MichaelSchlottke 我有一个程序,它执行许多独立的计算任务。我已经在每个任务中实现了OpenMP循环级别的并行化。然而,加速远远达不到理论值,并且严重依赖于循环长度。内存对我来说不是限制因素。在我的代码中,只有完成任务后才需要通信,这需要几分钟的时间才能完成。你认为在我的用例中,仅使用MPI(将任务分配给节点核心)的解决方案是否比混合方法更有效?非常感谢! - neil_mccauley
@neil_mccauley:这要看情况。如果你的计算任务非常独立,不需要太多通信,那么使用MPI并行化是值得一试的。如果每隔几分钟才需要通信,它的扩展性应该是线性的(完美的),而且你也不需要实现那么多。然而,如果你已经使用OpenMP进行了循环级别的并行化,为什么要删除它呢?只需要检查是否同时使用两者可以更快(虽然在你的情况下似乎不是这样)。 - Michael Schlottke-Lakemper
@MichaelSchlottke:我的计算任务是松散耦合的(这是一种进化算法)。我想要移除使用OpenMP进行细粒度并行化的原因是为了“节省”CPU核心,因为在我的情况下它根本不具备可扩展性。我更愿意使用MPI来利用那些核心。我也在考虑使用OpenMP对任务进行并行化。在共享内存环境中,使用OpenMP比MPI更好吗? - neil_mccauley

31

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

至于问题本身,根据所提供的信息,正确答案始终是一个: 取决于具体情况


4

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

如果您计划将来转移到分布式内存机器,则使用MPI。这样可以避免解决同一问题两次。

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


3
为了更好地理解,混合编程已经变得流行起来,因为OpenMP从缓存拓扑中获益,通过使用相同的地址空间。由于MPI可能会在内存中复制相同的数据(因为进程无法共享数据),所以它可能会受到缓存取消的影响。
另一方面,如果您正确分区您的数据,并且每个处理器都有一个私有缓存,那么您的问题可能完全适合缓存。在这种情况下,您将获得超线性加速。
谈论缓存时,最近的处理器有非常不同的缓存拓扑,并且始终如此:IT DEPENDS...

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接