在 Openmp 讲座中,类似的代码显示为 Openmp 中的竞争条件。在 for 循环中,sum+= 不在临界区,因此线程执行的顺序会改变结果。
但是在我的程序中不是这样的。无论我多久运行一次这个程序,总和总是打印为 285 (1²+2²+3²+4²+5²+6²+7²+8²+9²)。我的程序中似乎根本没有任何竞争条件。
int main()
{
int sum = 0;
int a[10];
int b[10];
for (int counter = 0; counter < 10; counter++) {
a[counter] = counter;
b[counter] = counter;
}
#pragma omp parallel for shared(sum)
for (int i = 0; i < 10; i++) {
sum += a[i] * b[i];
}
cout << "sum is " << sum; // always prints 285
std::cin.get();
return 0;
}
讲座特别告诉我这个程序不应该打印出正确的总和。为了解决这个问题,他们告诉我们使用 #pragma omp critical
或 reduction(+:sum)
最佳答案
仅仅因为它在您的机器上使用您的编译器和您的编译器选项没有表现出错误行为不会 表示没有错误。
不同的编译器、不同的优化选项或不同的硬件很可能会暴露错误。
竞争条件很棘手,因为在许多情况下或许多配置中,它们通常不会真正表现为问题(除了在您最大的客户生产数月后的深夜)。 竞态条件仍然是错误和未定义行为(这意味着您的编译器可以假设它们不存在,并且可能实际上使用该假设并因此巧妙地错误编译程序的其他部分)。
事实是,当多个线程正在修改同一个变量(或一些正在修改而一些正在读取)时,您需要同步对共享变量的访问 - 总是 - 不参加比赛。
关于c++ - Openmp 程序在没有临界区的情况下工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54852154/