1

我有一个非常奇怪的问题,我试图解决和理解。我有以下形式的嵌套 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;
    }
  }
}

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

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

现在来奇怪的部分。

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

另外,如果我不使用collapse, 或collapse(2)代替collapse(3),我会得到不同的结果。只有使用上述#pragma语句,我才能在Array[3*IJK + 1]循环中得到正确的结果。

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

这可能是什么原因?

4

1 回答 1

0

你确定你的序列号是正确的吗?

你的IJK计算对我来说毫无意义;一方面,它根本不依赖j。事实上,如果两个线程得到相同的 (i,k) 对和不同collapse(3)的 j——当然可能——就会出现竞争条件,因为它们都将尝试写入同一个 IJK。

你确定你不想要类似的东西吗

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

?

于 2012-08-15T20:13:01.757 回答