11

我有一些与研究相关的问题。

目前我已经完成了基于 MPI 的结构骨架框架工作的实现(具体使用openmpi 6.3)。框架应该在单机上使用。现在,我将它与其他以前的骨架实现(例如scandiumfast-flow,..)进行比较

我注意到的一件事是我的实现的性能不如其他实现。我认为这是因为,我的实现基于 MPI(因此需要匹配发送和接收操作的双向通信),而我与之比较的其他实现基于共享内存。(......但我仍然没有很好的解释来推理,这是我问题的一部分)

这两个类别的完成时间存在很大差异。

今天我也介绍了open-mpi的共享内存配置=> openmpi-sm

我的问题来了。

第一,为共享内存配置 MPI 意味着什么?我的意思是,当 MPI 进程存在于它们自己的虚拟内存中时;以下命令中的标志到底是什么?(我认为在 MPI 中,每次通信都是通过显式传递消息,进程之间不共享内存)。

    shell$ mpirun --mca btl self,sm,tcp -np 16 ./a.out

第二为什么与为共享内存开发的其他骨架实现相比,MPI 的性能要差这么多?至少我也在一台多核机器上运行它。(我想这是因为其他实现使用了线程并行编程,但我对此没有令人信服的解释)。

非常欢迎任何建议或进一步讨论。

如果我需要进一步澄清我的问题,请告诉我。

感谢您的时间!

4

1 回答 1

14

Open MPI 是非常模块化的。它有自己的组件模型,称为模块化组件架构 (MCA)。这是--mca参数名称的来源 - 它用于为 MCA 参数提供运行时值,由 MCA 中的不同组件导出。

每当给定通信器中的两个进程想要相互通信时,MCA 会找到合适的组件,这些组件能够将消息从一个进程传输到另一个进程。如果两个进程都驻留在同一个节点上,Open MPI 通常会选择共享内存 BTL 组件,称为sm. 如果两个进程驻留在不同的节点上,Open MPI 会遍历可用的网络接口并选择可以连接到另一个节点的最快的一个。它对 InfiniBand 等快速网络设置了一些首选项(通过openibBTL 组件),但如果您的集群没有 InfiniBand,如果tcpBTL 组件在允许的 BTL 列表中,则使用 TCP/IP 作为备用。

默认情况下,您无需执行任何特殊操作即可启用共享内存通信。只需使用mpiexec -np 16 ./a.out. 您链接到的是 Open MPI FAQ 的共享内存部分,它提供了有关sm可以调整 BTL 的哪些参数以获得更好性能的提示。我使用 Open MPI 的经验表明,默认参数几乎是最优的并且工作得很好,即使在像多级 NUMA 系统这样的奇特硬件上也是如此。请注意,默认的共享内存通信实现会将数据复制两次——一次从发送缓冲区到共享内存,一次从共享内存到接收缓冲区。以KNEM的形式存在一个快捷方式内核设备,但您必须下载并单独编译它,因为它不是标准 Linux 内核的一部分。借助 KNEM 支持,Open MPI 能够在同一节点上的进程之间执行“零复制”传输——复制由内核设备完成,它是从第一个进程的内存直接复制到第二个进程的内存过程。这极大地改善了驻留在同一节点上的进程之间的大消息传输。

另一种选择是完全忘记 MPI 并直接使用共享内存。您可以使用 POSIX 内存管理接口(参见此处)创建一个共享内存块,让所有进程直接对其进行操作。如果数据存储在共享内存中,这可能是有益的,因为不会制作副本。但要注意现代多插槽系统上的 NUMA 问题,其中每个插槽都有自己的内存控制器,并且从同一板上的远程插槽访问内存速度较慢。进程固定/绑定也很重要 - 传递--bind-to-socketmpiexec它以将每个 MPI 进程固定到单独的 CPU 内核。

于 2012-11-21T22:24:29.510 回答