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的值。