C语言 在不同机器上具有不同输出的并行代码



当我在两台不同的机器上运行下面的代码时,我得到不同的输出,其中一台的输出是正确的(sum = sum2),而另一台则不是。

我不知道为什么

#include <stdio.h>
#include <math.h>
#include <omp.h>
int main(){
const int NX=1000;    
const int NY=1000;
float x[NX+2];          
float y[NX+2];          
float u[NX+2][NY+2];    
float x2;   // 
float y2;
float sum;
float sum2;
for (int i=0; i<NX+2; i++){
for (int j=0; j<NY+2; j++){
x2      = i;
y2      = j;
u[i][j] = x2+ y2;
sum += u[i][j];
}
}
for (int i=0; i<NX+2; i++){
#pragma omp parallel for
for (int j=0; j<NY+2; j++){
x2      = i;
y2      = j;
u[i][j] = x2+ y2;
}
}
for (int i=0; i<NX+2;i++){
for (int j=0; j<NY+2; j++){
sum2 += u[i][j];
}
}
printf("%f n", sum);
printf("%f", sum2);
}

您需要初始化

的值
float sum;
float sum2;
sum += u[i][j];

sum2 += u[i][j];

导致未定义的行为。这就是为什么你会看到两个不同的结果

设置两个变量为零:

float sum = 0;
float sum2 = 0;

用(至少)-Wall标志编译你的代码。如果您这样做了,您将看到以下警告:

main.c:17:7: warning: 'sum2' may be used uninitialized in this function [-Wmaybe-uninitialized]
17 | float sum2;
|       ^~~~
main.c:16:7: warning: 'sum' may be used uninitialized in this function [-Wmaybe-uninitialized]
16 | float sum;
|       ^~~

性能方面,而不是并行的内部循环:

for (int i=0; i<NX+2; i++){
#pragma omp parallel for
for (int j=0; j<NY+2; j++){
x2      = i;
y2      = j;
u[i][j] = x2+ y2;
}
}

您应该通过使用OpenMP折叠选项来分析并行两个循环时会发生什么

#pragma omp parallel for collapse(2)
for (int i=0; i<NX+2; i++){       
for (int j=0; j<NY+2; j++){
u[i][j] = i + j;
}
}

即使collapse条款不是意见(例如:(比较慢),但在性能方面,并行化外部循环比并行化内部循环更好。首先,您可以避免多次创建并行区域NX+2的开销。其次,由于外部循环遍历列,而内部循环遍历行,因此在线程之间划分第一个循环的迭代减少了错误共享的可能性。

此外,您还可以并行化其他两个循环。但是,您需要使用OpenMP缩减子句来避免在sum和sum2变量更新期间出现竞争条件。

最终代码如下所示:

#include <stdio.h>
#include <math.h>
#include <omp.h>
int main(){
const int NX=1000;    
const int NY=1000;

float u[NX+2][NY+2];    
float sum = 0;
float sum2 = 0;
#pragma omp parallel for reduction(+:sum)
for (int i=0; i<NX+2; i++){
for (int j=0; j<NY+2; j++){
sum += i+j;
}
}
#pragma omp parallel for
for (int i=0; i<NX+2; i++){
for (int j=0; j<NY+2; j++){
u[i][j] = i+j;
}
}
#pragma omp parallel for reduction(+:sum2)
for (int i=0; i<NX+2;i++){
for (int j=0; j<NY+2; j++){
sum2 += u[i][j];
}
}
printf("%f n", sum);
printf("%f", sum2);
}

相关内容

  • 没有找到相关文章

最新更新