在 MPICH 中执行混合 OpenMP/MPI 作业
Posted
技术标签:
【中文标题】在 MPICH 中执行混合 OpenMP/MPI 作业【英文标题】:Executing hybrid OpenMP/MPI jobs in MPICH 【发布时间】:2016-02-15 06:24:00 【问题描述】:我正在努力寻找使用 MPICH (hydra) 执行混合 OpenMP/MPI 作业的正确方法。
我可以轻松启动这些进程,并且它们确实会创建线程,但无论我尝试过哪种类型的 -bind-to
,它们都被绑定到与其主线程相同的核心。
如果我将GOMP_CPU_AFFINITY
明确设置为0-15
,我会分散所有线程,但仅在每个节点有1 个进程时才提供。我不希望这样,我希望每个套接字一个进程。
设置OMP_PROC_BIND=false
没有明显效果。
我尝试过的许多不同组合的示例
export OMP_NUM_THREADS=8
export OMP_PROC_BIND="false"
mpiexec.hydra -n 2 -ppn 2 -envall -bind-to numa ./a.out
我得到的是所有进程都坐在一个核心 0-7
上,100% 和几个线程在核心 8-15
但只有一个接近 100%(他们正在等待第一个进程)。
【问题讨论】:
【参考方案1】:当 MPI 库和 OpenMP 运行时在默认情况下不能很好地协作时,当运行混合的 MPI/OpenMP 代码时,我确实有一个稍微不同的解决方案来将 OpenMP 线程绑定到套接字/NUMA 节点。这个想法是使用numactl
及其绑定属性。这甚至具有额外的优势,不仅将线程绑定到套接字,还绑定内存,从而强制实现良好的内存局部性并最大化带宽。
为此,我首先禁用任何 MPI 和/或 OpenMP 绑定(前者使用相应的 mpiexec
选项,后者将 OMP_PROC_BIND
设置为 false
)。然后我使用下面的omp_bind.sh
shell 脚本:
#!/bin/bash
numactl --cpunodebind=$(( $PMI_ID % 2 )) --membind=$(( $PMI_ID % 2 )) "$@"
我以这种方式运行我的代码:
OMP_PROC_BIND="false" OMP_NUM_THREADS=8 mpiexec -ppn 2 -bind-to-none omp_bind.sh a.out args
根据机器上的套接字数量,2
需要在 shell 上进行调整。同样,PMI_ID
取决于使用的mpiexec
的版本。我有时看到MPI_RANK
、PMI_RANK
等。
但无论如何,我总能找到一种让它工作的方法,而且内存绑定有时非常方便,尤其是为了避免 IO 缓冲区耗尽第一个 NUMA 节点上的所有内存的潜在陷阱,从而导致代码的内存对于在第一个套接字上运行的进程,在第二个 NUMA 节点上分配内存。
【讨论】:
有趣。您是否正在使用numactl --membind
,因为 MPICH 和兄弟姐妹无法自行进行内存绑定? Open MPI 进行内存绑定,甚至在共享内存传输中实现一些 NUMA 优化。只是出于好奇而询问 - 我是 Open MPI(在很小程度上是英特尔 MPI)用户,而 MPICH 和 co 对我来说非常陌生。
@HristoIliev TBH,我很久以前就计划这样做,因为有时我必须在未正确配置 MPI 的机器上运行性能测试。以这种方式使用numactl
比尝试修复 MPI 配置要简单得多。而此时 OpenMP 还没有任何原生绑定。如今,我主要是英特尔 MPI 用户,但我不太确定那里是如何管理内存绑定的。可以肯定的是,这个旧的 numactl
技巧在需要时仍然有效,此外,通过自愿设置错误,它允许评估代码对代码的潜在 NUMA 影响
感谢您的其他选择。我会调查这两个。我有一些性能问题,看看效果会很有趣。【参考方案2】:
由于libgomp
缺少英特尔KMP_AFFINITY
的respect
子句的等效项,您可以通过提供一个从/proc/PID/status
(Linux 特定)读取允许的CPU 列表的包装脚本来破解它:
#!/bin/sh
GOMP_CPU_AFFINITY=$(grep ^Cpus_allowed_list /proc/self/status | grep -Eo '[0-9,-]+')
export GOMP_CPU_AFFINITY
exec $*
这应该适用于-bind-to numa
。
【讨论】:
我想你想要grep ^Cpus_allowed_list /proc/self/status | grep -Eo '[0-9,-]+'
,这行得通!
实际上我错过了cat
,但你的更好。以上是关于在 MPICH 中执行混合 OpenMP/MPI 作业的主要内容,如果未能解决你的问题,请参考以下文章