for (uint i = 0; i < x; i++) {
   for (uint j = 0; j < z; j++) {
           if (inFunc(p, index)) {
                XY[2*nind] = i;
                XY[2*nind + 1] = j;
                nind++;
           }
   }
}

这里x = 512和z = 512并且nind = 0最初
和XY [2 * x * y]。

我想使用openMP优化此for循环,但是'nind'变量与for循环紧密地绑定(bind)在一起。我不知道,因为我也在检查条件,因此在某些情况下,如果跳过跳过增量或输入增量nind,它将不会输入。 openMP线程将递增nind变量,因为先到先递增nind。有什么办法可以解除绑定(bind)。 (“绑定(bind)”我的意思是只能串行实现)。

最佳答案

在这种情况下,一种典型的对缓存友好的解决方案是在私有(private)数组中收集(i,j)对,然后在最后将这些私有(private)数组连接起来,最后根据需要对结果进行排序:

#pragma omp parallel
{
  uint myXY[2*z*x];
  uint mynind = 0;

  #pragma omp for collapse(2) schedule(dynamic,N)
  for (uint i = 0; i < x; i++) {
    for (uint j = 0; j < z; j++) {
      if (inFunc(p, index)) {
        myXY[2*mynind] = i;
        myXY[2*mynind + 1] = j;
        mynind++;
      }
    }
  }

  #pragma omp critical(concat_arrays)
  {
    memcpy(&XY[2*nind], myXY, 2*mynind*sizeof(uint));
    nind += mynind;
  }
}

// Sort the pairs if needed
qsort(XY, nind, 2*sizeof(uint), compar);

int compar(const uint *p1, const uint *p2)
{
   if (p1[0] < p2[0])
     return -1;
   else if (p1[0] > p2[0])
     return 1;
   else
   {
     if (p1[1] < p2[1])
       return -1;
     else if (p1[1] > p2[1])
       return 1;
   }
   return 0;
}

您应该在N子句中试验不同的schedule(dynamic,N)值,以便在开销(对于N的较小值)和负载不平衡(对于N的较大值)之间取得最佳平衡。比较函数compar可能以更优化的方式编写。

这里的假设是合并和排序数组的开销很小。是否会这样取决于许多因素。

关于c++ - openMP用于循环增量语句处理,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35426767/

10-12 03:15