mpirun --cpu-set vs. --rankfile(Open MPI)1.4.5

时间:2013-06-05 21:18:09

标签: mpi openmpi pinning

我想准确地将我的MPI流程固定到(物理)核心列表中。我指的是mpirun --help输出的以下几点:

   -cpu-set|--cpu-set <arg0>  
                         Comma-separated list of ranges specifying logical
                         cpus allocated to this job [default: none]

...

   -rf|--rankfile <arg0>  
                         Provide a rankfile file

我的处理器的拓扑结构如下:

-------------------------------------------------------------
CPU type:       Intel Core Bloomfield processor 
*************************************************************
Hardware Thread Topology
*************************************************************
Sockets:        1 
Cores per socket:       4 
Threads per core:       2 
-------------------------------------------------------------
HWThread        Thread          Core            Socket
0               0               0               0
1               0               1               0
2               0               2               0
3               0               3               0
4               1               0               0
5               1               1               0
6               1               2               0
7               1               3               0
-------------------------------------------------------------
Socket 0: ( 0 4 1 5 2 6 3 7 )
-------------------------------------------------------------

现在,如果我使用 mpirun -np 2 --cpu-set 0,1 --report-bindings ./solver 启动我的程序,程序会正常启动但不考虑 - -cpu-set 我提供的参数。另一方面用 mpirun -np 2 --rankfile rankfile --report-bindings ./solver 启动我的程序给出了以下输出:

[neptun:14781] [[16333,0],0] odls:default:fork binding child [[16333,1],0] to slot_list 0
[neptun:14781] [[16333,0],0] odls:default:fork binding child [[16333,1],1] to slot_list 1

确实使用 top 进行检查显示,mpirun实际上使用了指定的内核。但是我应该如何解释这个输出呢?除了主机( neptun )和指定的插槽( 0,1 ),我没有线索。与我尝试的其他命令相同:

$mpirun --np 2 --bind-to-core --report-bindings ./solver
[neptun:15166] [[15694,0],0] odls:default:fork binding child [[15694,1],0] to cpus 0001
[neptun:15166] [[15694,0],0] odls:default:fork binding child [[15694,1],1] to cpus 0002

$mpirun --np 2 --bind-to-socket --report-bindings ./solver
[neptun:15188] [[15652,0],0] odls:default:fork binding child [[15652,1],0] to socket 0 cpus 000f
[neptun:15188] [[15652,0],0] odls:default:fork binding child [[15652,1],1] to socket 0 cpus 000f

使用 - bind-to-core top 命令再次显示核心0和1被使用,但为什么输出 cpus 0001 0002 - bind-to-socket 会导致更多混乱:2x 000f

我用最后一段来总结我的实验中提出的问题:
  - 为什么我的 - cpu-set 命令不起作用?   - 我应该如何解释 - report-bindings 输出产生的输出?

亲切的问候

1 个答案:

答案 0 :(得分:3)

在这两种情况下,输出都与您告诉Open MPI完全匹配。 cpus ...中的十六进制数表示进程允许的CPU(关联掩码)。这是一个位字段,每个位代表一个逻辑CPU。

--bind-to-core每个MPI进程都绑定到自己的CPU核心。等级0([...,0])将其关联掩码设置为0001,这意味着逻辑CPU 0.等级1([...,1])将其关联掩码设置为0002,这意味着逻辑CPU 1.逻辑CPU编号可能与输出中的HWThread标识符和拓扑信息匹配。

使用--bind-to-socket,每个MPI进程都绑定到套接字的所有核心。在您的特定情况下,关联掩码设置为000f或二进制0000000000001111,这对应于套接字中的所有四个核心。每个核心只分配一个超线程。

您可以进一步指示Open MPI如何选择多插槽节点上的套接字。使用--bysocket时,套接字以循环方式选择,即第一个排名放在第一个套接字上,下一个排名放在下一个套接字上,依此类推,直到每个套接字有一个进程,然后下一个等级再次放在第一个插座上,依此类推。使用--bycore,每个套接字接收的连续排名与该套接字中的核心数一样多。

我建议您阅读Open MPI 1.4.x的mpirun手册,尤其是Process Binding部分。这里有一些例子说明了不同的绑定选项如何相互作用。手册中没有提到--cpu-set选项,尽管Jeff Squyres在processor affinity features in Open MPI上编写了一个很好的页面(大约是v1.5,但大多数(如果不是全部的话)也适用于v1.4)