21

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 parallel for 会有类似的东西,如果你有足够多的线程让它有意义,那么累积将通过二叉树发生。

4

5 回答 5

9

现在可以使用适用于 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;
  } 
}

输出:

100
100
100
100
100
100

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

请注意,虽然这是一种方便的语法,但它可能会因为每个线程创建每个数组部分的副本而导致大量开销。

于 2016-11-07T17:14:25.567 回答
3

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

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

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

于 2010-10-24T17:37:41.757 回答
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/

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

于 2016-05-13T21:01:09.580 回答
1

OpenMP 无法对数组或结构类型变量执行归约(请参阅限制)。

您可能还想阅读privateandshared子句。 private声明一个变量对每个线程都是私有的,其中 asshared声明一个变量在所有线程之间共享。我还发现这个问题的答案对于 OpenMP 和数组非常有用。

于 2010-10-22T01:38:01.223 回答
0

从 OpenMP 4.5 开始,OpenMP 可以执行此操作,而 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必须与您计划减少的向量相匹配。

于 2017-06-14T07:20:47.803 回答