![](/img/trans.png)
[英]OpenMP: 2 Nested For loops inside of a While loop. How to fix for multi-threaded functionality? (Jacobi Solver)
[英]How to use OpenMP on nested for loops in a while loop?
我最近接触了 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? 另外,我不确定是否可以将 OpenMP 用于我的 while 循环,因为它需要先计算内部循环,然后才能确定它是否需要再次运行。
假设代码有效,您可以进行以下改进:
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]);
}
}
}
}
无需每次都创建一个parallel region
,您可以通过仅为整个代码创建一个来改进。 此外,由于您仅使用2
线程,因此负载平衡问题并不多,但是如果您要增加线程数,您可能会通过使用chunk = 1
的static
调度获得更好的性能。
您不需要将循环变量x
和y
设为private
,OpenMP 会为您完成。 在你最后的嵌套循环中,你有e = e + abs(A[x][y] - B[x][y]);
所以您可能希望线程具有添加“e”的结果,因此您应该使用reduction (+:e)
来减少跨线程的变量“e”。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.