系统配置:
Workstation with two Xeon E5-2620 V4 CPUs. Cent OS 7.3.
Openmpi-3.0.1, ifort 2015, gcc 4.8.6, intel MKL.我在工作站上运行MPI/OpenMP混合程序。我想使用8个OpenMP线程的1 MPI进程。但是,并行区中使用的OpenMP线程数始终为1。在另一台使用英特尔9900K处理器的机器上,OpenMP线程数始终为2。对于这两台机器,我都通过调用omp_get_max_threads打印了OMP_NUM_THREADS。因为我已经设置了"export OMP_NUM_THREADS=8“,所以OMP_NUM_THREADS是8。这真的很烦人。
经过大约一天的挖掘,我意识到这与Openmpi参数"-bind-to“有关。如果使用"-bind-to none“或"-bind-to numa”,程序运行良好,因为每个MPI进程的CPU使用率为800%,并且在并行区获得8倍的加速。如果我使用默认值"-bind-to core“。OpenMP线程的数量总是不是我所期望的。因此,在配备至强2640的工作站上,我们禁用了超线程,因此实际使用的openmp线程数始终为1。对于配备英特尔i7-9900K的PC,启用了超线程,因此使用的OMP线程数为2。
此外,如果不使用"-bind-to none/numa“参数,则omp_get_num_procs返回1。如果使用"-bind-to none”,则omp_get_num_procs返回处理器( CPU Core)的数量,而使用"-bind-to numa“时,omp_get_num_procs返回一个CPU中CPU核心的数量。
我在这里发布了我的经验,可以帮助其他人遇到类似的问题。
发布于 2019-06-23 03:33:00
正如Gilles in comment所指出的,在混合MPI + OpenMP运行中,有两个地方可以使用cpu集。第一个是MPI库和mpirun (mpiexec)程序,它在可用节点及其可用CPU上执行MPI进程分发(在hwloc的帮助下)。然后,每个启动的MPI进程将有一些允许的逻辑CPU核心来工作,并且OpenMP (多线程)库将尝试在这些可用的资源上工作。OpenMP库(gcc的libgomp或英特尔的&llvm的openmprtl.org)可以检查一组允许的核心,以决定要使用的线程数量。
当你想要"N个MPI进程与K个OpenMP线程“时,你应该检查你的mpirun是否会为每个MPI进程提供K个允许的核心。并且mpirun不会考虑你的OMP_NUM_THREADS环境变量。
OpenMPI的mpirun有一个有用的选项--report-bindings来查看实际运行中允许的设置。它还有许多(不太容易使用的)选项来更改绑定,如手册页https://www.open-mpi.org/doc/v4.0/man1/mpirun.1.php中所述
您可以尝试使用mpirun -n 1 --report-bindings true来查看实际的绑定,而无需启动程序。对于1个MPI进程和每个进程8个核心,请尝试选项"--cpus-per-proc <#perproc> - Bind each process to the指定数量的cpus“。
mpirun -n 1 --cpus-per-proc 8 --report-bindings true此选项已弃用,但它仍然可以工作,而且它比"--map-by <obj>:PE=n“容易得多。(我现在还不能完全理解这个变体。可能--map-by socket或--bind-by socket可以帮助您将mpi进程绑定到CPU芯片的所有可用内核上。)
要找出逻辑cpu核心到超线程和实际cpu核心的映射,您可以使用hwloc库及其工具lstopo https://www.open-mpi.org/projects/hwloc/doc/v2.0.4/a00312.php#cli_examples。
https://stackoverflow.com/questions/56714425
复制相似问题