前几天我想到,在我经常使用的OpenMP中实现最小/最大缩减的一段代码可能实际上不正确:
在某些情况下,当OpenMP min-max reduction子句不可用时(旧的OpenMP版本)或者我也需要最大值的索引,我使用的代码如下:
#pragma omp parallel private(myMax,myMax_idx) shared(globalMax,globalMax_idx)
{
#pragma omp for
for (...) {
}
if (myMax >= globalMax) {
#pragma omp critical
{
if ((myMax > globalMax)||(myMax == globalMax && globalMax_idx < myMax_idx) {
globalMax = myMax;
globalMax_idx = myMax_idx;
}
}
}
}
现在我想到,这段代码实际上可能会产生错误的结果,因为共享变量并不意味着所有线程都访问相同的内存部分,但是它们可能会使用私有副本不与所有其他线程保持同步。
所以我需要使用#pragma omp flush
来同步变量。
[...]
#pragma omp flush(globalMax)
if (myMax > globalMax) {
#pragma omp critical
{
if (myMax > globalMax) globalMax = myMax;
}
}
[...]
在M. Süß et al, Common Mistakes in OpenMP and How To Avoid Them中,此实现被描述为
这实质上是使用max运算符重新实现减少。
但是我想知道这段代码是否正确,因为我没有看到写作线程将他的版本globalMax
刷新到内存中。
同样在搜索索引的情况下,我还需要刷新globalMax_idx
变量。正确?
这个问题与
有关flush
,所以我不确定它是否真的很强大。因此,如果该代码来自&#34; OpenMP中的常见错误&#34;假设关键区域执行刷新是否真的值得在globalMax
之前明确刷新if
- 变量?
我应该使用什么代码?