error: reduction variable is private in outer context (omp reduction)
error: reduction variable is private in outer context (omp reduction)
我对下面两种情况下变量acc的数据共享范围感到困惑。在案例 1 中,我得到以下编译错误:error: reduction variable ‘acc’ is private in outer context
,而案例 2 编译没有任何问题。
根据 this article 在并行区域外定义的变量是共享的。
为什么添加 for 循环并行性私有化 acc?
在这种情况下,我如何累积在 for 循环中计算的结果并将循环的迭代 space 分布到线程组?
案例 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
确实是该隐式并行区域的私有对象。这就是编译器所抱怨的。
您的案例 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
之外。
我对下面两种情况下变量acc的数据共享范围感到困惑。在案例 1 中,我得到以下编译错误:error: reduction variable ‘acc’ is private in outer context
,而案例 2 编译没有任何问题。
根据 this article 在并行区域外定义的变量是共享的。
为什么添加 for 循环并行性私有化 acc? 在这种情况下,我如何累积在 for 循环中计算的结果并将循环的迭代 space 分布到线程组?
案例 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
确实是该隐式并行区域的私有对象。这就是编译器所抱怨的。
您的案例 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
之外。