【发布时间】:2015-04-13 12:07:36
【问题描述】:
我遇到了一个包含折叠子句的 OpenMP 代码,这对我来说是新的。我试图理解它的含义,但我认为我没有完全理解它的含义;我发现的一个定义是:
COLLAPSE:指定嵌套循环中有多少个循环应该被折叠到一个大的迭代空间中,并根据调度子句进行划分。所有关联循环中迭代的顺序执行决定了折叠迭代空间中迭代的顺序。
我以为我明白这意味着什么,所以我尝试了以下简单程序:
int i, j;
#pragma omp parallel for num_threads(2) private(j)
for (i = 0; i < 4; i++)
for (j = 0; j <= i; j++)
printf("%d %d %d\n", i, j, omp_get_thread_num());
生产的
0 0 0
1 0 0
1 1 0
2 0 0
2 1 0
2 2 1
3 0 1
3 1 1
3 2 1
3 3 1
然后我添加了collapse(2) 子句。我希望在前两列中得到相同的结果,但现在在最后一列中有相同数量的 0 和 1。
但我得到了
0 0 0
1 0 0
2 0 1
3 0 1
所以我的问题是:
- 我的代码发生了什么?
- 什么情况下应该使用
collapse? - 您能否提供一个示例来说明使用
collapse与不使用collapse之间的区别?
【问题讨论】:
-
好问题。您正在尝试融合三角形双环。我不认为崩溃适用于此。它需要是一个方形双环。 Others on SO have said collapse works with triangular loops。我还没有阅读规范。如果您想融合一个三角形循环,请查看此question。虽然,我现在知道使用归纳变量的更好方法。
-
但是如果是方形双循环,使用collapse有什么好处呢?无论哪种方式,每个线程都将获得相同数量的迭代。
-
如果你在折叠之前有两个嵌套循环在
n和m上,每个线程都会得到n/nthreads迭代,而在你折叠之后它是n*m迭代。这可以帮助例如当n相对于nthreads不是很大但n*m是。 -
如果您使用 C99,它可以省去私有化循环索引的麻烦... #pragma omp parallel for for (int i = 0; i
-
当前未折叠的输出不正确,每个线程显示 5 个输出——对于线程 #0,应该只为外部循环值 0 和 2(即 0 0 0、2 0 0、2 1 0 ) 其他输出应该是线程#1。