c++ - 错误: reduction variable is private in outer context (omp reduction)

标签 c++ parallel-processing openmp simd

我对以下两种情况中变量 acc 的数据共享范围感到困惑。在情况 1 中,我收到以下编译错误:错误:缩减变量“acc”在外部上下文中是私有(private)的,而情况 2 编译时没有任何问题。

根据this article并行区域之外定义的变量是共享的。

为什么添加 for 循环并行性会使 acc 私有(private)化? 在这种情况下,我如何累积 for 循环中计算的结果并在线程团队中分配循环的迭代空间?

案例1

            float acc = 0.0f;
            
            #pragma omp for simd reduction(+: acc)
            for (int k = 0; k < MATRIX_SIZE; k++) {
                float mul = alpha;
                mul *=  a[i * MATRIX_SIZE + k];
                mul *=  b[j * MATRIX_SIZE + k];
                acc += mul;
            }

案例2

            float acc = 0.0f;
            
            #pragma omp simd reduction(+: acc)
            for (int k = 0; k < MATRIX_SIZE; k++) {
                float mul = alpha;
                mul *=  a[i * MATRIX_SIZE + k];
                mul *=  b[j * MATRIX_SIZE + k];
                acc += mul;
            }


最佳答案

您的情况 1 违反了 OpenMP 语义,因为存在一个包含 acc 定义的隐式并行区域(请参阅 OpenMP Language Terminology,“顺序部分”)。因此,acc 确实是该隐式并行区域私有(private)的。这就是编译器提示的地方。

您的情况 2 的不同之处在于 simd 构造不是工作共享构造,因此对 reduction 子句的语义有不同的定义。

如果你这样写的话,情况 1 是正确的:

void example(void) {
    float acc = 0.0f;

    #pragma omp parallel for simd reduction(+: acc)
    for (int k = 0; k < MATRIX_SIZE; k++) {
        float mul = alpha;
        mul *=  a[i * MATRIX_SIZE + k];
        mul *=  b[j * MATRIX_SIZE + k];
        acc += mul;
    }
}

现在,acc 变量是在 for simd 构造绑定(bind)到的 parallel 之外定义的。

关于c++ - 错误: reduction variable is private in outer context (omp reduction),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67709887/

相关文章:

c# - 如何在 VS 2013 中调试 Windows Phone (8) 运行时组件或 C++ DLL 中的 C++ 代码

c++ - 将成员函数作为参数传递给C++中的另一个函数

c++ - $fp == $rbp 在 gdb 中吗?

c++ - 如何正确升级您的 OpenMP 版本?

c++ - 在 for-loop : compiler bug? 中重新排序测试条件

python - 在python上并行执行和文件写入

arrays - 两个数组的元素相加

java - 带屏障的进程间同步

c++ - c=c+a*b 的 OpenMP 4 simd 矢量化

c++ - 使用 C++、libpng 和 OpenMP 并行创建 PNG 文件