执行矩阵/向量乘法时,在使用OpenMP并行运行代码时,或者在单个线程中运行代码时,我会得到两个不同的值。如果我导出环境变量
$ export OMP_NUM_THREADS=1
乘法给出相同的结果,但是如果我将值设置为2或更高,则乘法有时是一致的,有时则不一致。
#include <stdio.h>
#include <math.h>
#include <omp.h>
double* parMatVecMul(double* A, double* v, int M, int N){
double* C = new double[M];
double dot;
#pragma omp parallel for
for (int i = 0; i<M; i++)
{
dot = 0;
for (int j=0; j<N; j++)
dot += *((A+i*N) + j) * v[j];
C[i] = dot;
}
return C;
}
double* matVecMul(double* A, double* v, int M, int N){
double* C = new double[M];
double dot;
for (int i = 0; i<M; i++)
{
dot = 0;
for (int j=0; j<N; j++)
dot += *((A+i*N) + j) * v[j];
C[i] = dot;
}
return C;
}
int main(){
int size = 40;
double* mat = new double[size*size];
double* x_true = new double[size];
double* b = new double[size];
double* bx = new double[size];
for( int iter = 0; iter < 10; iter++){ //Run code 10 times to find error
for( int i =0; i < size; i++) //Initialize symmetric matrix
for( int j =0; j < size; j++){
mat[i*size + j] = rand() / double(RAND_MAX) + 0.2;
mat[j*size + i] = mat[i*size + j];
}
for( int i =0; i < size; i++){ //Make matrix diagonally dominant
mat[i*size + i] += size;
x_true[i] = rand() % 10 + 0.2;
}
double error = 0;;
b = matVecMul(mat, x_true, size, size);
bx = parMatVecMul(mat, x_true, size, size);
for (int i = 0; i < size; i++)
error += fabs(b[i] - bx[i]);
printf("b error: %f\n", error);
}
return 0;
}
输出:
$ ./a.out
b error: 0.000000
b error: 0.000000
b error: 0.000000
b error: 0.000000
b error: 0.000000
b error: 0.000000
b error: 0.000000
b error: 34.747142
b error: 0.000000
b error: 0.000000
为什么并行操作有时不正确?