是否可以使用openmp对数组进行减少?

And*_*ner 19 c++ arrays openmp reduction

OpenMP本身是否支持减少表示数组的变量?

这可能会像以下一样......

float* a = (float*) calloc(4*sizeof(float));
omp_set_num_threads(13);
#pragma omp parallel reduction(+:a)
for(i=0;i<4;i++){
   a[i] += 1;  // Thread-local copy of a incremented by something interesting
}
// a now contains [13 13 13 13]
Run Code Online (Sandbox Code Playgroud)

理想情况下,对于omp并行会有类似的东西,并且如果你有足够多的线程使它有意义,那么积累将通过二叉树发生.

dec*_*lts 5

现在,可以使用适用于C和C ++的OpenMP 4.5来减少阵列。这是一个例子:

#include <iostream>

int main()
{

  int myArray[6] = {};

  #pragma omp parallel for reduction(+:myArray[:6])
  for (int i=0; i<50; ++i)
  {
    double a = 2.0; // Or something non-trivial justifying the parallelism...
    for (int n = 0; n<6; ++n)
    {
      myArray[n] += a;
    }
  }
  // Print the array elements to see them summed   
  for (int n = 0; n<6; ++n)
  {
    std::cout << myArray[n] << " " << std::endl;
  } 
}
Run Code Online (Sandbox Code Playgroud)

输出:

100
100
100
100
100
100
Run Code Online (Sandbox Code Playgroud)

我使用GCC 6.2进行了编译。您可以在此处查看哪些常见的编译器版本支持OpenMP 4.5功能:http : //www.openmp.org/resources/openmp-compilers/

请注意,从上面的注释中可以看出,尽管这是一种方便的语法,但它可能会为每个线程创建每个数组节的副本而产生大量开销。


And*_*ner 3

仅适用于 OpenMP 3.0 中的 Fortran,并且可能仅适用于某些编译器。

请参阅最后一个示例(示例 3):

http://wikis.sun.com/display/openmp/Fortran+Allocatable+Arrays

  • 从 OpenMP 4.5 开始就可以了;见下面陈江的回答。基本上,您必须指定_arraysections_(请参见 OpenMP 4.5 规范第 44 页第 2.4 节)。你的 #pragma 规范看起来像这样: `#pragma omp parallelduction(+:a[:4])` 但是要小心,你必须意识到每个线程都会分配自己版本的数组部分;如果您在具有多个线程的大型数组上执行此操作,则可能会导致内存需求爆炸。 (3认同)