【问题标题】:error: reduction variable is private in outer context (omp reduction)错误:归约变量在外部上下文中是私有的(omp归约)
【发布时间】:2021-08-14 23:47:12
【问题描述】:

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

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

为什么添加 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-processing openmp simd


    【解决方案1】:

    您的案例 1 违反了 OpenMP 语义,因为存在一个包含 acc 定义的隐式并行区域(参见 OpenMP Language Terminology,“顺序部分”)。因此,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 变量现在定义在 for simd 构造绑定到的 parallel 之外。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-23
      • 2023-04-04
      • 1970-01-01
      • 2016-02-16
      • 1970-01-01
      • 2022-01-23
      相关资源
      最近更新 更多