c++ - 在与 OpenMP 并行化的嵌套 for 循环中写入共享数组(通过指针)如何产生错误结果?

标签 c++ openmp

我有一个非常奇怪的问题,我正在尝试解决和理解。我有一个以下形式的嵌套 for 循环:

#pragma omp parallel for schedule(guided) shared(Array) collapse(3)
for (int i=istart; i<iend; i++)
{
  for (int j=jstart; j<jend; j++)
  {
    for(int k=kstart; k<kend; k++)
    {
       Int IJK = (i*(jend-jstart) + (j-jstart))*(kend-kstart) + (k-kstart);
       Array[3*IJK + 2] = an operation with some shared values;
    }
  }
}

这种形式有3个循环,分别是Array[3*IJK]Array[3*IJK + 1]Array[3*IJK +2] 分别。 Array 实际上也是一个共享指针,对于 IJK 的值,实际上调用了一个函数(内联)。

我首先尝试并行化所有循环并且程序运行通过,但结果与我的串行结果不同。

现在是奇怪的部分。

具有相同结构但具有 Array[3*IJK + 1] 的 for 循环在并行化时会产生正确的结果(在这种情况下其他循环是串行的)。但是,一旦我将其他循环之一并行化,我就会得到不同的结果。只有这个循环在其自身并行化时才能产生正确的结果。

此外,如果我不使用 collapsecollapse(2) 而不是 collapse(3),我会得到不同的结果.只有使用上面的 #pragma 语句,我才能在 Array[3*IJK + 1] 循环中得到正确的结果。

我认为这可能与写入 Array 的顺序有关,但是使用有序的子句和构造,我仍然得到错误的结果。

这可能是什么原因?

最佳答案

你确定你的连环案例是正确的吗?

你的IJK 计算对我来说毫无意义;一方面,它根本不依赖于 j。实际上,如果两个线程获得相同的 (i,k) 对,但 j 不同——使用 collapse(3) 肯定是可能的——将出现竞争条件,因为它们都将尝试写入同一个 IJK。

你确定你不想要这样的东西吗

   Int IJK = (i*(jend-jstart) + (j-jstart))*(kend-kstart) + (k-kstart);

?

关于c++ - 在与 OpenMP 并行化的嵌套 for 循环中写入共享数组(通过指针)如何产生错误结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11976161/

相关文章:

c++ - boost::interprocess 共享内存 : how to have multiple different shared memory on same machine

C++ 和 OpenMP : undefined reference to GOMP_loop_dynamic_start

c++ - 是否返回语句复制值

c++ - 是否可以使用另一个 lua 文件中定义的表,而该文件不需要作为当前文件中的模块?

c++ - 在 Visual Studio 2010 中将项目从 Win32 移植到 x64 平台后加载了不正确的 ComCtl32.dll

c++ - 避免并发访问变量

c++ - Eigen 与 OpenMP : No parallelisation due to false sharing and thread overhead

c - Openmp for 在循环中,在哪里播种随机数生成器?

c++ - c=c+a*b 的 OpenMP 4 simd 矢量化

c++ - 未输入 If-block,不知道为什么