每个核心分配两个 MPI 进程
Posted
技术标签:
【中文标题】每个核心分配两个 MPI 进程【英文标题】:assign two MPI processes per core 【发布时间】:2012-07-29 18:07:16 【问题描述】:如何为每个内核分配 2 个 MPI 进程?
例如,如果我使用mpirun -np 4 ./application
,那么它应该使用 2 个物理内核来运行 4 个 MPI 进程(每个内核 2 个进程)。我正在使用 Open MPI 1.6。我做了mpirun -np 4 -nc 2 ./application
,但无法运行它。
它抱怨mpirun was unable to launch the specified application as it could not find an executable:
【问题讨论】:
可能是因为你拼错了application? 没有。那只是错字。 “应用程序”不是真正的应用程序名称。感谢您指出。如果我把'-nc 2'拿出来,它就起作用了! 在您的评论中,您说的是“nc -2”而不是“-nc 2”。那是 2 条消息中的 2 处错别字。你确定你不是因为赶时间而错过了一些愚蠢的事情吗? :-( 我仔细检查过。实际命令中没有拼写错误。没有'-nc 2'的情况下工作 我建议你在这里合并你other question的内容。 【参考方案1】:orterun
(Open MPI SPMD/MPMD 启动器;mpirun/mpiexec
只是它的符号链接)对进程绑定有一些支持,但它不够灵活,无法让您在每个内核上绑定两个进程。您可以尝试使用-bycore -bind-to-core
,但是当所有内核都已经分配了一个进程时,它会出错。
但有一个解决方法 - 您可以使用 rankfile 在其中明确指定将每个排名绑定到哪个插槽。下面是一个示例:为了在双核 CPU 上运行 4 个进程,每个核心有 2 个进程,您可以执行以下操作:
mpiexec -np 4 -H localhost -rf rankfile ./application
其中rankfile
是一个文本文件,内容如下:
rank 0=localhost slot=0:0
rank 1=localhost slot=0:0
rank 2=localhost slot=0:1
rank 3=localhost slot=0:1
这会将等级 0 和 1 放在处理器 0 的核心 0 上,并将等级 2 和 3 放在处理器 0 的核心 1 上。丑陋但有效:
$ mpiexec -np 4 -H localhost -rf rankfile -tag-output cat /proc/self/status | grep Cpus_allowed_list
[1,0]<stdout>:Cpus_allowed_list: 0
[1,1]<stdout>:Cpus_allowed_list: 0
[1,2]<stdout>:Cpus_allowed_list: 1
[1,3]<stdout>:Cpus_allowed_list: 1
编辑:从您的other question 可以清楚地看出您实际上是在超线程 CPU 上运行。然后你必须弄清楚你的逻辑处理器的物理编号(这有点令人困惑,但物理编号对应于processor:
的值,如/proc/cpuinfo
中报告的那样)。获取它的最简单方法是安装hwloc
库。它提供了hwloc-ls
工具,您可以这样使用:
$ hwloc-ls --of console
...
NUMANode L#0 (P#0 48GB) + Socket L#0 + L3 L#0 (12MB)
L2 L#0 (256KB) + L1 L#0 (32KB) + Core L#0
PU L#0 (P#0) <-- Physical ID 0
PU L#1 (P#12) <-- Physical ID 12
...
物理 ID 列在括号中的 P#
之后。在您的 8 核情况下,第一个核心(核心 0)的第二个超线程很可能具有 ID 8
,因此您的 rankfile 看起来像:
rank 0=localhost slot=p0
rank 1=localhost slot=p8
rank 2=localhost slot=p1
rank 3=localhost slot=p9
(注意 p
前缀 - 不要省略)
如果您没有hwloc
或者您无法安装它,那么您必须自己解析/proc/cpuinfo
。超线程将具有相同的 physical id
和 core id
值,但不同的 processor
和 apicid
。物理ID等于processor
的值。
【讨论】:
对于未来的旅行者,我有一个后续问题here【参考方案2】:我不确定您是否有多台机器,以及您希望如何分配进程的确切细节,但我会考虑阅读:
mpirun man page
手册表明它有将进程绑定到不同事物的方法,包括节点、套接字和 cpu 核心。
请务必注意,如果您运行的进程数是 CPU 内核数的两倍,您就可以实现这一点,因为它们往往会均匀分布在内核上以共享负载。
我会尝试以下类似的方法,尽管手册有些含糊,而且我不能 100% 确定它会按预期运行,只要您有双核:
mpirun -np 4 -npersocket 4 ./application
【讨论】:
我正在使用共享内存选项在一台机器上运行应用程序, 此使用的解决方法是-npersocket 4
。只需将其设置为每个插槽上 CPU 核心数的两倍,它就会为每个核心调度 2 个进程。它们不会与核心绑定,但会自行分配。【参考方案3】:
如果你使用 PBS 或类似的东西,我会建议这种提交方式:
qsub -l select=128:ncpus=40:mpiprocs=16 -v NPROC=2048./pbs_script.csh
在目前的提交中,我选择了 128 个计算节点,它们有 40 个核心,并使用其中的 16 个。就我而言,我每个节点有 20 个物理内核。
在这个提交中,我阻止了节点的所有 40 个核心,没有人可以使用这些资源。它可以避免其他人使用同一节点并与您的工作竞争。
【讨论】:
【参考方案4】:使用Open MPI 4.0,两条命令:
mpirun --oversubscribe -c 8 ./a.out
和
mpirun -map-by hwthread:OVERSUBSCRIBE -c 8 ./a.out
为我工作(我有一个具有 4 个内核和 8 个逻辑内核的 Ryzen 5 处理器)。
我使用包含实数运算的 do 循环进行了测试。使用了所有逻辑线程,但似乎没有加速优势,因为与使用 -c 4
选项(没有超额订阅)相比,计算花费了两倍的时间。
【讨论】:
【参考方案5】:你可以跑
mpirun --use-hwthread-cpus ./application
在这种情况下,Open MPI 会认为处理器是超线程提供的线程。这与将处理器视为 CPU 内核时的默认行为形成对比。
Open MPI 在您使用此选项时将超线程提供的线程表示为“硬件线程”,并为每个“硬件线程”分配一个 Open MPI 处理器。
【讨论】:
以上是关于每个核心分配两个 MPI 进程的主要内容,如果未能解决你的问题,请参考以下文章