首页 > 解决方案 > 错误:归约变量在外部上下文中是私有的(omp归约)

问题描述

在流动的两种情况下,我对变量acc的数据共享范围感到困惑。在案例 1 中,我得到以下编译错误:error: reduction variable ‘acc’ is private in outer context,而案例 2 编译没有任何问题。

根据这篇文章,在并行区域之外定义的变量是共享的。

为什么添加 for-loop 并行性私有化acc?在这种情况下,我如何累积在 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;
            }


标签: c++parallel-processingopenmpsimd

解决方案


您的案例 1 违反了 OpenMP 语义,因为存在一个包含acc. 因此,acc确实是该隐式并行区域的私有。这就是编译器所抱怨的。

您的案例 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变量现在parallelfor simd构造绑定到的之外定义。


推荐阅读