c++ - 打开 : check if nested parallesim

标签 c++ openmp

假设我有一个方法将两个 std::vector 相乘:

double multiply(std::vector<double> const& a, std::vector<double> const& b){
    double tmp(0);
    /*here I could easily do a parallelization with*/
    /*#pragma omp parallel loop for*/
    for(unsigned int i=0;i<a.size();i++){
        tmp += a[i]*b[i];
    }
    return tmp;
}

如果我在此函数中设置 pragma 宏,将运行对 multiply(...) 的调用 在所有线程上。

现在假设我想在其他地方做很多 vector 乘法:

void many_multiplication(std::vector<double>* a, std::vector<double>* b, unsigned int N){
    /*here I could easily do a parallelization with*/
    /*#pragma omp parallel loop for*/
    for(unsigned int i=0;i<N;i++){
        for(unsigned int j=0;j<N;j++){
            multiply(a[i],b[j]);
        }
    }
}

我也可以用同样的方式进行并行化。但这会导致 不需要的嵌套并行性。

我如何检查是否在并行区域内调用了 multiply(..), 然后 multiply(...)pragma 宏被“关闭”。如果它被称为 来自非平行区域,然后它“打开”。

最佳答案

嵌套并行性默认禁用,除非通过设置 OMP_NESTED 专门启用至 true或调用 omp_set_nested(1); (OpenMP specification 的第 2.3.2 节)按照 Avi Ginsburg 的建议明确修改嵌套设置是个坏主意。相反,您应该使用基于嵌套级别的条件并行执行:

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

omp_get_active_level()返回调用时封闭线程的事件并行区域的数量。它返回 0如果从平行区域外部或不活动的外部区域调用。感谢if(active_level < 1)子句,只有当并行区域未包含在事件区域​​中时,并行区域才会被激活,即并行运行,无论嵌套设置如何。

如果您的编译器不支持 OpenMP 3.0 或更高版本(例如,任何版本的 MS Visual C/C++ 编译器),则 omp_in_parallel() call 可以改用:

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

omp_in_parallel()如果至少一个封闭的平行区域处于事件状态,则返回非零值,但不提供有关嵌套深度的信息,即灵 active 稍差。

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

关于c++ - 打开 : check if nested parallesim,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31520326/

相关文章:

multithreading - 使用 OMP 循环展开

c - 并行化阶乘计算

c++ - OpenMP 矩阵乘法嵌套循环

c++ - Qt/SQL - 从没有记录的表中获取列类型和名称

c++ - 64 位 Windows 上应用程序可用的最大内存是多少

c++ - openmp并行性能

c - 使用 openmp 确保缓冲区访问是私有(private)的

c++ - 为什么下面的语句不起作用?

c++ - for循环C++中的额外增量

c++ - 如何绕过不受支持的 C++11 代码