【发布时间】:2011-04-16 01:34:18
【问题描述】:
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 会有类似的东西,如果你有足够多的线程让它有意义,那么累积将通过二叉树发生。
【问题讨论】:
-
也许你可以解释一下你想要做什么。提供序列号可能会有所帮助。
-
再挖掘一下,听起来“仅在 fortran 中”就是答案。我最终只是在循环之外分配了一个大型本地副本数组,让线程在 for 循环中累积到它们自己的副本,然后在 for 循环之后累积到一个全局数组中,仍然在并行区域内,在 a关键部分。
-
更深入地挖掘,这里有一篇类似的研究论文,但它还没有在 openmp 中。 springerlink.com/content/tq76655852630525
-
如果你想减少开销,你可以使用 atomic 而不是 critical 来保护单个添加(甚至是锁数组);您甚至可以使用共享数组而不是私有数组,并尝试使用自己的二进制归约。但这会很丑。
-
我最终手动为数组的线程本地副本分配空间。每个线程将 1/8 的累加到其本地副本中,然后线程将其本地副本累加到 #pragma omp 关键块内的全局副本中。由于核心数 (8) 远小于 n,因此同步开销可以忽略不计。它不漂亮,但它有效。
标签: c++ arrays openmp reduction