C++ OpenMP矩阵乘法给出了不一致的结果
在执行矩阵/向量乘法时,使用OpenMP并行运行代码或在单个线程中运行代码时,我会得到两个不同的值。如果我导出环境变量C++ OpenMP矩阵乘法给出了不一致的结果,c++,openmp,C++,Openmp,在执行矩阵/向量乘法时,使用OpenMP并行运行代码或在单个线程中运行代码时,我会得到两个不同的值。如果我导出环境变量 $ export OMP_NUM_THREADS=1 乘法给出了相同的结果,但如果我将值设置为2或更高,乘法有时是一致的,有时是不一致的 #include <stdio.h> #include <math.h> #include <omp.h> double* parMatVecMul(double* A, double* v, int
$ 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;
}
为什么并行操作有时不正确 给点局部作用域而不是共享作用域。在并行化函数中,
dot
上存在一个竞争——多个线程在没有协调的情况下更新它。一般来说,如果并行程序在一个线程上运行,但在多个线程上运行(不可靠),则考虑数据竞争@tim18已经告诉你如何解决这个问题了。
$ ./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