在您的代码示例中,只有外部循环是并行的。您可以通过在内部循环中打印来进行测试omp_get_thread_num()
,您会看到,对于给定i
的 ,线程 num 是相同的(当然,这个测试是说明性的而不是确定性的,因为不同的运行会给出不同的结果)。例如,使用:
#include <stdio.h>
#include <omp.h>
#define dimension 4
int main() {
#pragma omp parallel for
for (int i = 0; i < dimension; i++)
for (int j = 0; j < dimension; j++)
printf("i=%d, j=%d, thread = %d\n", i, j, omp_get_thread_num());
}
我得到:
i=1, j=0, thread = 1
i=3, j=0, thread = 3
i=2, j=0, thread = 2
i=0, j=0, thread = 0
i=1, j=1, thread = 1
i=3, j=1, thread = 3
i=2, j=1, thread = 2
i=0, j=1, thread = 0
i=1, j=2, thread = 1
i=3, j=2, thread = 3
i=2, j=2, thread = 2
i=0, j=2, thread = 0
i=1, j=3, thread = 1
i=3, j=3, thread = 3
i=2, j=3, thread = 2
i=0, j=3, thread = 0
至于其余代码,您可能希望在新问题中添加更多细节(从小示例中很难分辨),但例如,您不能将private(j)
whenj
仅在稍后声明。在我上面的示例中,它自动是私有的。我猜diff
这是我们在样本中看不到的变量。此外,循环变量i
是自动私有的(来自2.5 版规范- 与 3.0 版规范相同)
for 或并行 for 构造的 for 循环中的循环迭代变量在该构造中是私有的。
编辑:以上所有内容对于您和我展示的代码都是正确的,但您可能对以下内容感兴趣。对于 OpenMP 3.0 版(在例如gcc 4.4版中可用,但在 4.3 版中不可用)有一个collapse
子句,您可以按照自己的方式编写代码,但
#pragma omp parallel for collapse (2)
可以并行化两个 for 循环(请参阅规范)。
编辑:好的,我下载了 gcc 4.5.0 并运行了上面的代码,但是使用collapse (2)
得到以下输出,显示了现在并行化的内部循环:
i=0, j=0, thread = 0
i=0, j=2, thread = 1
i=1, j=0, thread = 2
i=2, j=0, thread = 4
i=0, j=1, thread = 0
i=1, j=2, thread = 3
i=3, j=0, thread = 6
i=2, j=2, thread = 5
i=3, j=2, thread = 7
i=0, j=3, thread = 1
i=1, j=1, thread = 2
i=2, j=1, thread = 4
i=1, j=3, thread = 3
i=3, j=1, thread = 6
i=2, j=3, thread = 5
i=3, j=3, thread = 7
如果您想并行化两个循环,此处的评论(搜索“Workarounds”)也与版本 2.5 中的解决方法相关,但上面引用的版本 2.5 规范非常明确(请参阅第A.35节中的不合格示例) .