我是 OpenMP 的新手,我正在尝试启动一个单独的线程来处理二维数组中的每个项目。
本质上,这是:
for (i = 0; i < dimension; i++) {
for (int j = 0; j < dimension; j++) {
a[i][j] = b[i][j] + c[i][j];
我正在做的是:
#pragma omp parallel for shared(a,b,c) private(i,j) reduction(+:diff) schedule(dynamic)
for (i = 0; i < dimension; i++) {
for (int j = 0; j < dimension; j++) {
a[i][j] = b[i][j] + c[i][j];
这实际上是否为每个 2D 项目启动了一个线程?我将如何测试它?如果错了,正确的做法是什么?谢谢!
注:代码已经大大简化
最佳答案
在您的代码示例中只有外部循环是并行的。您可以通过在内循环中打印 omp_get_thread_num()
进行测试,您会看到,对于给定的 i
,线程数是相同的(当然,这个测试是说明性的而不是确定性的,因为不同的运行会给出不同的结果)。例如,与:
#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)
当 j
仅在稍后声明时。在我上面的例子中它是自动私有(private)的。我想 diff
是我们在示例中看不到的变量。此外,循环变量 i
是自动私有(private)的(来自 version 2.5 spec - 在 3.0 规范中相同)
The loop iteration variable in the for-loop of a for or parallel for construct is private in that construct.
编辑:以上所有内容对于您和我所展示的代码都是正确的,但您可能对以下内容感兴趣。对于 OpenMP 版本 3.0(在例如 gcc version 4.4 中可用,但不是版本 4.3)有一个 collapse
子句,您可以在其中编写代码,但是
#pragma omp parallel for collapse (2)
并行化两个 for 循环(参见 the spec)。
编辑:好的,我下载了 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
评论 here如果您想并行化两个循环,(搜索“变通办法”)也与 2.5 版中的变通办法相关,但上面引用的 2.5 版规范非常明确(参见 A.35 部分中的不合格示例)。
关于c - 为 OpenMP 中的每个内部循环启动一个线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2215818/