首页 > 解决方案 > 使用 mpirun 运行时未激活 OpenMP 线程

问题描述

在尝试运行混合 MPI/OpenMP 应用程序时,我意识到 OpenMP 线程的数量始终为 1,即使我导出了OMP_NUM_THREAS=36. 我构建了一个显示问题的小型 C++ 示例:

#include <vector>
#include "math.h"

int main ()
{
    int n=4000000,  m=1000;
    double x=0,y=0;
    double s=0;
    std::vector< double > shifts(n,0);


    #pragma omp parallel for reduction(+:x,y)
    for (int j=0; j<n; j++) {

        double r=0.0;
        for (int i=0; i < m; i++){

            double rand_g1 = cos(i/double(m));
            double rand_g2 = sin(i/double(m));

            x += rand_g1;
            y += rand_g2;
            r += sqrt(rand_g1*rand_g1 + rand_g2*rand_g2);
        }
        shifts[j] = r / m;
    }
}

我使用以下代码编译代码g++

g++ -fopenmp main.cpp

OMP_NUM_THREADS仍然设置为 36。当我运行代码时:

time ./a.out

我得到了大约 6 秒的运行时间htop,并按预期显示了使用本地节点的所有 36 个内核的命令。当我运行它时mpirun

time mpirun -np 1 ./a.out

我得到了 3 分 20 秒的运行时间,并htop显示该命令仅在一个核心上使用。我也尝试过使用mpirun -np 1 -x OMP_NUM_THREADS=36 ./a.out,但结果是一样的。

我正在使用 GCC 9.2.0 和 OpenMPI 4.1.0a1。由于这是开发人员版本,我也尝试过使用 OpenMPI 4.0.3,结果相同。

知道我缺少什么吗?

标签: mpiopenmp

解决方案


Open MPI 的默认行为是

  • 如果有两个或更少的 MPI 任务,则在核心上绑定 MPI 任务
  • 否则将 MPI 任务绑定到套接字

所以你真的应该

mpirun --bind-to none -np 1 ./a.out

这样您的 MPI 任务就可以访问主机的所有内核。


推荐阅读