【问题标题】:OpenMP set_num_threads() is not workingOpenMP set_num_threads() 不工作
【发布时间】:2012-06-21 03:48:04
【问题描述】:

我正在使用 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;
}

程序输出:

sum = 4.5e+007
threads=1

如何控制线程数?

【问题讨论】:

    标签: c++ multithreading numbers set openmp


    【解决方案1】:

    除了在您的情况下在并行区域之外调用 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_DYNAMIC 设置为false 来禁用动态团队。

    要强制执行给定数量的线程,您应该禁用动态团队并使用 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 ...
    }
    

    或使用num_threads OpenMP 子句:

    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 ...
    }
    

    【讨论】:

    • 但是我无法通过更改线程数以及设置 omp_set_dynamic(0) 来获得任何加速??
    • 首先,serial 版本在我的 CPU 上需要 50 毫秒。由于 OpenMP 开销,您不能期望这种快速代码的加速。在循环中增加 100 倍的交互。其次,您在原始代码中缺少 parallel 区域。你写了#pragma omp for ...,而它应该是#pragma omp parallel for ...。第三,您正在混合 MPI 和 OpenMP。你确定你知道自己在做什么吗?
    • @HristoIliev 用户可以动态控制线程数吗?即,而不是使用硬编码的4。使用变量?
    • @manatttta,是的。每次在程序执行期间遇到并行区域时,该值都会传递给 OpenMP 运行时库,因此使用变量可以按预期工作。
    • @OmarHaque,是的,num_threads 子句也接受变量,因此可以在运行时控制线程数。
    【解决方案2】:

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

    【讨论】:

    【解决方案3】:

    根据GCC manual for omp_get_num_threads

    在程序的连续部分中,omp_get_num_threads 返回 1

    所以这个:

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

    应该改为:

    #pragma omp parallel
    {
        cout<<"sum="<<sum<<endl;
        cout<<"threads="<<omp_get_num_threads()<<endl;
    }
    

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

    【讨论】:

      【解决方案4】:

      我也遇到了同样的问题。下面给出解决方案

      右键单击 Source Program > Properties > Configuration Properties > C/C++ > Language > 现在将 Open MP support flag 更改为 Yes...。

      你会得到想要的结果。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-26
        • 2017-02-23
        • 1970-01-01
        • 2012-05-15
        • 1970-01-01
        相关资源
        最近更新 更多