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

时间:2010-09-23 02:55:36

标签: 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]

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

5 个答案:

答案 0 :(得分:5)

现在,OpenMP 4.5 for C和C ++可以减少数组。这是一个例子:

#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;
  } 
}

输出:

100
100
100
100
100
100

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

从上面的注释中注意到虽然这是方便的语法,但它可能会为每个线程创建每个数组部分的副本而调用很多开销。

答案 1 :(得分:3)

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

参见上一个例子(例3):

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

答案 2 :(得分:2)

现在最新的openMP 4.5规范支持减少C / C ++数组。 http://openmp.org/wp/2015/11/openmp-45-specs-released/

最新的GCC 6.1也支持此功能。 http://openmp.org/wp/2016/05/gcc-61-released-supports-openmp-45/

但我还没试过。希望其他人可以测试此功能。

答案 3 :(得分:1)

OpenMP无法对数组或结构类型变量执行缩减(请参阅restrictions)。

您还可以阅读privateshared条款。 private声明一个变量对每个线程都是私有的,其中shared声明一个变量在所有线程之间共享。我还发现这个question的答案对于OpenMP和数组非常有用。

答案 4 :(得分:0)

OpenMP可以执行此操作,因为OpenMP 4.5和GCC 6.3(可能更低)支持它。示例程序如下所示:

#include <vector>
#include <iostream>

int main(){
  std::vector<int> vec;

  #pragma omp declare reduction (merge : std::vector<int> : omp_out.insert(omp_out.end(), omp_in.begin(), omp_in.end()))

  #pragma omp parallel for default(none) schedule(static) reduction(merge: vec)
  for(int i=0;i<100;i++)
    vec.push_back(i);

  for(const auto x: vec)
    std::cout<<x<<"\n";

  return 0;
}

请注意,omp_outomp_in是特殊变量,declare reduction的类型必须与您计划减少的矢量相匹配。