我是OpenMP的新手,我正在尝试启动一个单独的线程来处理2D数组中的每个项目。
基本上,这个:
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项启动一个线程还是没有?我该如何测试?如果是错的,那么正确的方法是什么?谢谢!
注意:代码已经大大简化了
答案 0 :(得分:7)
在代码示例中只有外部循环是并行的。您可以通过在内循环中打印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
1}}仅在稍后声明。在我上面的例子中,它是自动私有的。我猜diff
是我们在样本中看不到的变量。此外,循环变量i
自动为私有(来自version 2.5 spec - 与3.0规范相同)
循环迭代变量 for for循环for for或parallel for 构造是私有的 构造
编辑:以上所有内容对于您和我展示的代码都是正确的,但您可能对以下内容感兴趣。对于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)部分中的示例。
答案 1 :(得分:0)
您可以尝试使用嵌套的omp并行fors(在omp_set_nested(1)
调用之后),但在所有openmp实现上都不支持它们。
所以我想制作一些2D网格并从单个网格开始网格上的所有线程(例如固定的4x4线程网格):
#pragma omp parallel for
for(k = 0; k < 16; k++)
{
int i,j,i_min,j_min,i_max,j_max;
i_min=(k/4) * (dimension/4);
i_max=(k/4 + 1) * (dimension/4);
j_min=(k%4) * (dimension/4);
j_max=(k%4 + 1) * (dimension/4);
for(i=i_min;i<i_max;i++)
for(j=j_min;j<j_max;j++)
f(i,j);
}