私有变量与减少 OMP
private variables vs reduction in OMP
我想了解 OMP 如何处理不同的 for
循环声明。我有:
int main()
{
int i, A[10000]={...};
double ave = 0.0;
#pragma omp parallel for reduction(+:ave)
for(i=0;i<10000;i++){
ave += A[i];
}
ave /= 10000;
printf("Average value = %0.4f\n",ave);
return 0;
}
其中 {...}
是从 1 到 10000 的数字。此代码打印正确的值。如果我使用 #pragma omp parallel for private(ave)
而不是 #pragma omp parallel for reduction(+:ave)
,那么 printf
的结果是 0.0000
。我想我明白 reduction(oper:list)
的作用,但想知道它是否可以替代 private
以及如何替代。
所以是的,您可以在没有 reduction
子句的情况下进行归约。但这有一些您必须了解的缺点:
- 你必须手工做事,这更error-prone:
- 声明局部变量以存储局部累加;
- 正确初始化它们;
- 积累进去;
- 使用
critical
构造对初始变量进行最终归约。
- 这更难理解和维护
- 这可能不太有效...
无论如何,这是一个使用您的代码的示例:
int main() {
int i, A[10000]={...};
double ave = 0.0;
double localAve;
#pragma omp parallel private( i, localAve )
{
localAve = 0;
#pragma omp for
for( i = 0; i < 10000; i++ ) {
localAve += A[i];
}
#pragma omp critical
ave += localAve;
}
ave /= 10000;
printf("Average value = %0.4f\n",ave);
return 0;
}
这是手动进行归约的经典方法,但请注意,本应声明为 reduction
的变量未在此处声明为 private
。变成 private
的是这个变量的局部替代,而全局变量必须保持 shared
.
我想了解 OMP 如何处理不同的 for
循环声明。我有:
int main()
{
int i, A[10000]={...};
double ave = 0.0;
#pragma omp parallel for reduction(+:ave)
for(i=0;i<10000;i++){
ave += A[i];
}
ave /= 10000;
printf("Average value = %0.4f\n",ave);
return 0;
}
其中 {...}
是从 1 到 10000 的数字。此代码打印正确的值。如果我使用 #pragma omp parallel for private(ave)
而不是 #pragma omp parallel for reduction(+:ave)
,那么 printf
的结果是 0.0000
。我想我明白 reduction(oper:list)
的作用,但想知道它是否可以替代 private
以及如何替代。
所以是的,您可以在没有 reduction
子句的情况下进行归约。但这有一些您必须了解的缺点:
- 你必须手工做事,这更error-prone:
- 声明局部变量以存储局部累加;
- 正确初始化它们;
- 积累进去;
- 使用
critical
构造对初始变量进行最终归约。
- 这更难理解和维护
- 这可能不太有效...
无论如何,这是一个使用您的代码的示例:
int main() {
int i, A[10000]={...};
double ave = 0.0;
double localAve;
#pragma omp parallel private( i, localAve )
{
localAve = 0;
#pragma omp for
for( i = 0; i < 10000; i++ ) {
localAve += A[i];
}
#pragma omp critical
ave += localAve;
}
ave /= 10000;
printf("Average value = %0.4f\n",ave);
return 0;
}
这是手动进行归约的经典方法,但请注意,本应声明为 reduction
的变量未在此处声明为 private
。变成 private
的是这个变量的局部替代,而全局变量必须保持 shared
.