使用OpenMP时如何平衡嵌套情况下的线程数?

时间:2017-11-16 09:44:32

标签: openmp

这个神话般的post教会了我很多,但我还有一个问题。对于以下代码:

double multiply(std::vector<double> const& a, std::vector<double> const& b){
    double tmp(0);
    int active_levels = omp_get_active_level();
    #pragma omp parallel for reduction(+:tmp) if(active_level < 1)
    for(unsigned int i=0;i<a.size();i++){
        tmp += a[i]+b[i];
    }
    return tmp;
}

如果从另一个并行部分调用multiply()

#pragma omp parallel for
for (int i = 0; i < count; i++) {
    multiply(a[i], b[i]);
}

因为外循环迭代取决于count变量,如果count是一个大数字,那么它是合理的。但是,如果count仅为1且我们的服务器是多核机器(例如,具有512核心),则multiply()函数仅生成1线。所以在这种情况下,服务器利用不足。顺便说一句,答案还提到:

  

无论如何,编写这样的代码是一种不好的做法。您应该简单地保留并行区域,并允许最终用户选择是否应该启用嵌套并行。

那么在使用OpenMP时如何平衡嵌套情况下的线程数?

1 个答案:

答案 0 :(得分:0)

考虑使用OpenMP任务(omp taskloop在一个并行部分和一个中间omp single)。这允许您在不同的嵌套级别上灵活地使用OpenMP中的线程,而不是手动定义每个级别的线程数或超额订阅OS线程。

然而,这会增加调度成本。在一天结束时,没有完美的解决方案总能做到最好。相反,你必须继续测量和分析你在实际输入上的表现。