使用flush重新实现OpenMPs最小/最大缩减的正确方法

时间:2014-11-19 09:26:26

标签: max openmp min flush reduction

前几天我想到,在我经常使用的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变量。正确?

这个问题与

有关

因此,如果该代码来自&#34; OpenMP中的常见错误&#34;假设关键区域执行刷新是否真的值得在globalMax之前明确刷新if - 变量?

我应该使用什么代码?

0 个答案:

没有答案