OpenMP set_num_threads()不起作用

Nur*_*lan 27 c++ multithreading numbers set openmp

我正在使用C++中的OpenMP编写并行程序.

我想控制程序中使用的线程数omp_set_num_threads(),但它不起作用.

#include <iostream>
#include <omp.h>
#include "mpi.h"

using namespace std;

int myrank;
int groupsize;
double sum;
double t1,t2;
int n = 10000000;

int main(int argc, char *argv[])
{
    MPI_Init( &argc, &argv);
    MPI_Comm_rank( MPI_COMM_WORLD, &myrank );
    MPI_Comm_size(MPI_COMM_WORLD,&groupsize);

    omp_set_num_threads(4);

    sum = 0;
    #pragma omp for  reduction(+:sum)
    for (int i = 0; i < n; i++)
        sum+= i/(n/10);

    cout<<"sum="<<sum<<endl;
    cout<<"threads="<<omp_get_num_threads()<<endl;

    MPI_Finalize();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

该方案产出:

sum = 4.5e+007
threads=1
Run Code Online (Sandbox Code Playgroud)

如何控制线程数?

Hri*_*iev 85

除了omp_get_num_threads()在您的情况下调用并行区域之外,调用omp_set_num_threads()仍然不能保证OpenMP运行时将使用指定数量的线程.omp_set_num_threads()用于覆盖环境变量的值OMP_NUM_THREADS,他们都控制上限线程队的OpenMP将产卵所有并行区域(在的情况下的尺寸OMP_NUM_THREADS),或用于任何随后的并行区域(一个呼叫之后omp_set_num_threads()) .如果运行时系统认为更合适,那么称为动态团队的东西仍然可以选择较少数量的线程.你可以通过调用禁用动态团队omp_set_dynamic(0)或通过设置环境变量OMP_DYNAMICfalse.

要强制执行给定数量的线程,您应该禁用动态团队并使用以下任一方式指定所需的线程数omp_set_num_threads():

omp_set_dynamic(0);     // Explicitly disable dynamic teams
omp_set_num_threads(4); // Use 4 threads for all consecutive parallel regions
#pragma omp parallel ...
{
    ... 4 threads used here ...
}
Run Code Online (Sandbox Code Playgroud)

或者使用num_threadsOpenMP子句:

omp_set_dynamic(0);     // Explicitly disable dynamic teams
// Spawn 4 threads for this parallel region only
#pragma omp parallel ... num_threads(4)
{
    ... 4 threads used here ...
}
Run Code Online (Sandbox Code Playgroud)

  • 首先,_serial_版本在我的CPU上需要50毫秒.由于OpenMP开销,您不能期望这种快速代码的加速.在循环中增加100倍的交互.其次,您在原始代码中缺少`parallel`区域.你已经写了`#pragma omp for ...`而它应该是`#pragma omp parallel for ...`.第三,你正在混合MPI和OpenMP.你确定你确切知道你在做什么吗? (7认同)
  • @OmarHaque,是的,“num_threads”子句也接受变量,因此可以控制运行时的线程数量。 (2认同)

Smi*_*Smi 19

omp_get_num_threads()函数返回当前在执行调用它的并行区域的团队中的线程数.你在并行区域之外调用它,这就是它返回的原因1.


jww*_*jww 8

根据omp_get_num_threadsGCC 手册

在程序的顺序部分 omp_get_num_threads 返回 1

所以这:

cout<<"sum="<<sum<<endl;
cout<<"threads="<<omp_get_num_threads()<<endl;
Run Code Online (Sandbox Code Playgroud)

应该改为:

#pragma omp parallel
{
    cout<<"sum="<<sum<<endl;
    cout<<"threads="<<omp_get_num_threads()<<endl;
}
Run Code Online (Sandbox Code Playgroud)

我使用的代码也遵循 Hristo 关于禁用动态团队的建议。