gpt4 book ai didi

c - 在不同机器上具有不同输出的并行代码

转载 作者:行者123 更新时间:2023-12-03 13:22:49 25 4
gpt4 key购买 nike

当我在两台不同的机器上运行下面的代码时,我得到了不同的输出,在一个输出中,输出是正确的(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];
导致 undefined behaviour。这就是为什么您看到两个不同的结果。
将两个变量都设置为零:
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 collapse选项分析两个循环并行化时发生的情况
#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时间的开销。其次,由于外部循环遍历列,内部循环遍历行,因此在线程之间划分第一个循环的迭代可降低 false-sharing的可能性。
此外,您还可以并行化其他两个循环。但是,您将需要使用 OpenMP reduction clause来避免在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);
}

关于c - 在不同机器上具有不同输出的并行代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66141833/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com