28

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

4

4 回答 4

57

您是否需要或想要 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,那么我会从那个开始,稍后再添加 OpenMP,当您知道您已经用尽了 MPI 的所有合理优化选项时。

于 2012-07-05T13:01:44.947 回答
31

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

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

于 2012-07-04T16:19:58.927 回答
4

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

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

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

于 2012-07-04T15:42:16.923 回答
3

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

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

通过谈论缓存,最近的处理器上有非常不同的缓存拓扑,并且始终:它取决于...

于 2012-07-04T21:30:42.323 回答