如何在while循环的嵌套for循环中使用OpenMP?
我最近被引入到OpenMP和并行编程中,并且在正确使用它时遇到了一些麻烦。如何在while循环的嵌套for循环中使用OpenMP?
我想在以下代码上实现OpenMP以使其运行速度更快。
int m = 101;
double e = 10;
double A[m][m], B[m][m];
for (int x=0; x<m; x++){
for (int y=0; y<m; y++){
A[x][y] = 0;
B[x][y] = 1;
}
}
while (e >= 0.0001){
for (int x=0; x<m; x++){
for (int y=0; y<m; y++){
A[x][y] = 0.25*(B[x][y] - 0.2);
}
}
e = 0;
for (int x=0; x<m; x++){
for (int y=0; y<m; y++){
e = e + abs(A[x][y] - B[x][y]);
}
}
}
我想层出不穷同时,而不是一个运行循环加快运行时间。我相信下面的代码应该可以工作,但我不确定我是否正确使用OpenMP。
int m = 101;
double e = 10;
double A[m][m], B[m][m];
#pragma omp parallel for private(x,y) shared(A,B) num_threads(2)
for (int x=0; x<m; x++){
for (int y=0; y<m; y++){
A[x][y] = 0;
B[x][y] = 1;
}
}
while (e >= 0.0001){
#pragma omp parallel for private(x,y) shared(A,B) num_threads(2)
for (int x=0; x<m; x++){
for (int y=0; y<m; y++){
A[x][y] = 0.25*(B[x][y] - 0.2);
}
}
// I want to wait for the above loop to finish computing before starting the next
#pragma omp barrier
e = 0;
#pragma omp parallel for private(x,y) shared(A,B,e) num_threads(2)
for (int x=0; x<m; x++){
for (int y=0; y<m; y++){
e = e + abs(A[x][y] - B[x][y]);
}
}
}
我是否正确使用OpenMP?另外,我不确定我是否可以在我的while循环中使用OpenMP,因为它需要在计算内部循环之前确定它是否需要再次运行。
假设代码工作,这里有一些改进,可以使:
int m = 101;
double e = 10;
double A[m][m], B[m][m];
#pragma omp parallel num_threads(2) shared(A, B)
{
#pragma omp for
for (int x=0; x<m; x++){
for (int y=0; y<m; y++){
A[x][y] = 0;
B[x][y] = 1;
}
}
while (e >= 0.0001){
#pragma omp for
for (int x=0; x<m; x++){
for (int y=0; y<m; y++){
A[x][y] = 0.25*(B[x][y] - 0.2);
}
}
#pragma omp single
e = 0;
#pragma omp for reduction (+:e)
for (int x=0; x<m; x++){
for (int y=0; y<m; y++){
e = e + abs(A[x][y] - B[x][y]);
}
}
}
}
而不是创建每次并行区域,你可以通过创建只有一个为整个代码改进。此外,由于您正在使用2个线程,所以没有太多的负载平衡问题,但是如果要增加线程数,则可以使用块= 1的静态调度获得更好的性能。
您不需要使循环x和y的变量是私有的,openmp将为你做到这一点。在嵌套的最后一个循环中,你有e = e + abs(A[x][y] - B[x][y]);
,所以你可能希望线程有添加'e'的结果,因此你必须使用“reduction(+:e)”来减少线程中的变量'e'。
为最后一个'for'嵌套的内部循环创建一个私有累加变量,并且每次迭代外部循环只更新(共享)'e'一次可能没有用处? –
是的,我现在正在加上那个 – dreamcrash
@dreamcrash在你的顶部#pragma omg应该是#pragma omp?此外,我计划将线程增加到32个,因为我有16个内核,每个内核有2个线程。我不明白你为什么使私人,减少(+:E)做什么? – PiccolMan
你说你相信下面的代码可以工作......嗯......是吗?如果没有,你会得到什么错误? –
另外,在omp parallel之后不需要屏障,因为在omp parallel blocks的末尾有一个隐含的屏障 –
不需要声明x和y私有。 – dreamcrash