el_*_*dor 5 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]
Run Code Online (Sandbox Code Playgroud)
...
-rf|--rankfile <arg0>
Provide a rankfile file
Run Code Online (Sandbox Code Playgroud)
我的处理器拓扑如下:
-------------------------------------------------------------
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 )
-------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)
现在,如果我使用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
Run Code Online (Sandbox Code Playgroud)
确实检查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
Run Code Online (Sandbox Code Playgroud)
和
$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
Run Code Online (Sandbox Code Playgroud)
随着--bind到核心的顶级命令再次向我表明内核0和1被使用,但为什么是输出的CPU 0001和技术?--bind-to-socket导致更多混乱:2x 000f ?
我使用最后一段来总结我的实验中出现的问题:
- 为什么我的--cpu-set命令不起作用?
- 我应该如何解释由--report-bindings输出产生的输出?
亲切的问候
在这两种情况下,输出都与您告诉 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每一个插座接收尽可能多的连续的行列是在插槽的内核数量。
我建议您阅读mpirunOpen MPI 1.4.x的手册,尤其是Process Binding部分。那里有一些关于不同绑定选项如何相互作用的示例。--cpu-set手册中没有提到该选项,尽管 Jeff Squyres在 Open MPI 中写了一个关于处理器亲和特性的不错的页面(它大约是 v1.5,但大部分(如果不是全部的话)也适用于 v1.4)。