OpenMP和MPI混合并行的环境配置

MPI一般用于不同的计算节点之间的并行,而OpenMP常用于在一台多核心服务器上的并行,两者都能够实现并行的功能,OpenMP和MPI混合编程是常见的使用方式。而我们在本地开发调试时,往往使用一台多核的服务器对MPI和OpenMP进行调试,在调试过程中会遇到这么一个问题:如何为程序分配MPI线程和OpenMP线程?

编译参数

bind-to

MPI分配的线程可以认为是一个计算节点所具有的线程,默认下是一个MPI线程一个物理线程。但可以通过
-bind-to命令可以为一个MPI线程分配不同的核心。命令如下:

1
mpiexec -n 4 bind-to core:4 codename // 一个MPI进程分配四个核心,一个有四个MPI进程

下面是bind-to的帮助信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
-bind-to: Process-core binding type to use

Binding type options:
Default:
none -- no binding (default)

Architecture unaware options:
rr -- round-robin as OS assigned processor IDs
user:0+2,1+4,3,2 -- user specified binding

Architecture aware options (part within the {} braces are optional):
board{:<n>} -- bind to 'n' motherboards
numa{:<n>} -- bind to 'n' numa domains
socket{:<n>} -- bind to 'n' sockets
core{:<n>} -- bind to 'n' cores
hwthread{:<n>} -- bind to 'n' hardware threads
l1cache{:<n>} -- bind to processes on 'n' L1 cache domains
l2cache{:<n>} -- bind to processes on 'n' L2 cache domains
l3cache{:<n>} -- bind to processes on 'n' L3 cache domains

OMP_PROC_BIND

绝大数HPC应用程序属于CPU计算密集型,对CPU的资源占用会长期处于100%状态,计算程序的进程或线程在不同核上的调度会导致性能下降。因此建议将线程与核绑定,并且计算线程总数不要超过节点的CPU核总数。

执行以下命令将OpenMP线程绑定到核:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
export OMP_PROC_BIND=close

有以下三种模式可以选择
spread
这是一种比较稀疏、均匀的绑定方式。如果有M个线程,N个处理器,那么在并行线程开始时首先会从串行线程运行的那个核开始分布,每个核上运行M/N个线程。
如果串行线程在p1上运行,而并行线程有4个线程,则分别分布在
p1、p3、p5、p7。
如果如果串行线程在p0上运行,而并行线程有16个线程,则会分别分布在p0上有线程0和线程1,p1上运行线程2和线程3,p3上运行线程4和线程5,p4上运行线程6和线程7,…,p7上运行线程14和线程15。

close
这是一种紧密的绑定方式。这种方式优先分配与串行线程相临近的核。当并行线程数超过核数时,分配方式与spread相近。
如果串行线程在p1上运行,进入并行线程时有4个线程,则分别分布在p1,p2,p3,p4。

master
master的意思是继承串行线程部分的核绑定,即全部由运行串行线程的那个核来运行所有的线程。

OMP_PLACES

OMP_PROC_BIND一样,OMP_PLACES也是OpenMP的一个环境变量,可以用来指定线程的位置。
OMP_PLACES有两种使用方式,一个是关键字的形式:

关键字 意义
threads 每个位置对应于目标机器上的单个硬件线程
cores 每个位置对应于目标机器上的单个核心(具有一个或多个硬件线程)。
sockets 每个位置对应于目标机器上的单个套接字(由一个或多个核心组成)。

另一种是指定某个具体的核,通过逗号分隔的位置列表或间隔来指定多个位置

1
2
3
4
5
6
export OMP_PLACES threads
export OMP_PLACES "threads(4)"
// 下面三个命令等价
export OMP_PLACES "{0,1,2,3},{4,5,6,7},{8,9,10,11},{12,13,14,15}"
export OMP_PLACES "{0:4},{4:4},{8:4},{12:4}"
export OMP_PLACES "{0:4}:4:4"

具体问题

1个MPI进程占据一个CPU, CPU中的多核分配为OpenMP线程

1
OMP_PROC_BIND=true OMP_PLACES=sockets mpiexec -n 1 -bind-to socket:2 ./mpi.o

多个进程, 每个进程多个线程.

1
OMP_PROC_BIND=true OMP_PLACES=cores  mpiexec -n 8 -bind-to core:7  ./mpi.o
作者

echo

发布于

2022-12-22

更新于

2024-08-10

许可协议

评论