确保混合MPI / OpenMP在不同的核心上运行每个OpenMP线程

问题描述 投票:2回答:2

我正在尝试运行混合的OpenMP / MPI作业,以便OpenMP线程由核心分隔(每个核心只有一个线程)。我已经看到其他使用numa-ctl和bash脚本来设置环境变量的答案,我不想这样做。

我希望能够通过在命令行上设置OMP_NUM_THREADS和/或OMP_PROC_BIND和mpiexec选项来完成此操作。我尝试了以下内容 - 假设我想要2个MPI进程,每个进程有2个OpenMP线程,并且每个线程都在不同的内核上运行,所以我想要总共4个内核。

OMP_PROC_BIND=true OMP_PLACES=cores OMP_NUM_THREADS=2 mpiexec -n 2 

这会分割作业​​,以便只有两个进程在工作,并且它们都在同一个CPU上,因此它们每个只使用大约25%的CPU。如果我尝试:

OMP_PROC_BIND=false OMP_PLACES=cores OMP_NUM_THREADS=2 mpiexec -n 2

然后,根据top,我只得到两个独立的MPI进程,每个进程运行100%或超过100%的CPU功率。这似乎并未显示用于OpenMP线程的不同核心。

如何强制系统将单独的线程放在单独的核心上?

仅供参考,lscpu打印此:

-CPU(s):                48
-On-line CPU(s) list:   0-47
-Thread(s) per core:    2
-Core(s) per socket:    12
-Socket(s):             2
-NUMA node(s):          2
mpi openmp hpc mpich
2个回答
1
投票

实际上,我希望你的第一个例子能够奏效。在此处设置OMP_PROC_BIND=true很重要,因此在固定线程时,OpenMP会保留在MPI进程的CPU绑定范围内。

根据批处理系统和MPI实现,可能有非常单独的方法来设置这些。

此外,超线程,或者通常每个核心的多个硬件线程,在Linux中都显示为“核心”,可能是问题的一部分,因为当两个进程在一个核心的两个超线程上运行时,您永远不会看到200%。

这是一个通用的解决方案,我在为某些MPI和某些系统上的某些OpenMP实现计算这些东西时使用。有来自Cray的文档,其中包含一个非常有用的程序,可以快速计算出这些内容,它被称为xthi.c,从here, section 9.8搜索文件名(不确定它是否合法过去...)。编译:

mpicc xthi.c -fopenmp -o xthi

现在我们可以看到究竟发生了什么,例如我们得到的具有超线程和英特尔MPI(基于MPICH)的2x 8 Core Xeon:

$ OMP_PROC_BIND=true OMP_PLACES=cores OMP_NUM_THREADS=2 mpiexec -n 2 ./xthi

Hello from rank 0, thread 0, on localhost. (core affinity = 0,16)
Hello from rank 0, thread 1, on localhost. (core affinity = 1,17)
Hello from rank 1, thread 0, on localhost. (core affinity = 8,24)
Hello from rank 1, thread 1, on localhost. (core affinity = 9,25)

正如您所看到的,核心意味着核心的所有超线程。注意默认情况下mpirun如何将它固定到不同的套接字上。使用OMP_PLACES=threads,每个核心可以获得一个线程:

$ OMP_PROC_BIND=true OMP_PLACES=threads OMP_NUM_THREADS=2 mpiexec -n 2 ./xthi
Hello from rank 0, thread 0, on localhost. (core affinity = 0)
Hello from rank 0, thread 1, on localhost. (core affinity = 1)
Hello from rank 1, thread 0, on localhost. (core affinity = 8)
Hello from rank 1, thread 1, on localhost. (core affinity = 9)

使用OMP_PROC_BIND=false(你的第二个例子),我得到:

$ OMP_PROC_BIND=false OMP_PLACES=cores OMP_NUM_THREADS=2 mpiexec -n 2 ./xthi
Hello from rank 0, thread 0, on localhost. (core affinity = 0-7,16-23)
Hello from rank 0, thread 1, on localhost. (core affinity = 0-7,16-23)
Hello from rank 1, thread 0, on localhost. (core affinity = 8-15,24-31)
Hello from rank 1, thread 1, on localhost. (core affinity = 8-15,24-31)

这里,每个OpenMP线程都获得一个完整的套接字,因此MPI排名仍然在不同的资源上运行。但是,一个进程内的OpenMP线程可以由OS跨所有核心进行大规模调度。这与在我的测试系统上设置OMP_NUM_THREADS=2相同。

同样,这可能取决于特定的OpenMP和MPI实现和版本,但我认为您将很容易弄清楚上面的描述发生了什么。

希望有所帮助。


2
投票

你可以试试这个

OMP_PROC_BIND=true OMP_PLACES=cores OMP_NUM_THREADS=2 mpiexec -bind-to core:2 -n 2 ./xthi

MPI任务绑定在两个核心上,OpenMP运行时将(希望)将每个线程绑定到分配给MPI任务的单个核心。

为了检查MPI绑定工作正常,你可以简单

$ mpiexec -np 2 -bind-to core:2 grep Cpus_allowed_list /proc/self/status
Cpus_allowed_list:  0-1
Cpus_allowed_list:  2-3
© www.soinside.com 2019 - 2024. All rights reserved.