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并行会有类似的东西,并且如果你有足够多的线程使它有意义,那么积累将通过二叉树发生。
答案 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)。
您还可以阅读private
和shared
条款。 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_out
和omp_in
是特殊变量,declare reduction
的类型必须与您计划减少的矢量相匹配。