我对以下两种情况中变量 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/