C++ Gauss-Seidel使用OpenMP |线性方程组求解
我正在使用OpenMP编写Gauss Seidel代码,以解线性方程组。 但是我没有得到正确的输出。 如果n设置为1,则输出正确。 不过,这个算法对我来说似乎是正确的。 有人能帮忙吗? 代码:C++ Gauss-Seidel使用OpenMP |线性方程组求解,c++,openmp,linear-algebra,C++,Openmp,Linear Algebra,我正在使用OpenMP编写Gauss Seidel代码,以解线性方程组。 但是我没有得到正确的输出。 如果n设置为1,则输出正确。 不过,这个算法对我来说似乎是正确的。 有人能帮忙吗? 代码: intseidel\p(双*A,双*b,双*x,intn) { 双*dx; dx=(双*)calloc(n,sizeof(双)); intε=1.0e-4; int i,j,k,id; 双dxi; 双和; 对于(int i=0;i,除非你有很好的理由自己做这件事,否则不要这样做。有很多库可以做这件事(甚至
intseidel\p(双*A,双*b,双*x,intn)
{
双*dx;
dx=(双*)calloc(n,sizeof(双));
intε=1.0e-4;
int i,j,k,id;
双dxi;
双和;
对于(int i=0;i,除非你有很好的理由自己做这件事,否则不要这样做。有很多库可以做这件事(甚至更多)。Eigen是一个只包含标题的库,请查看它
您还可以使用BLAS/LAPACK,其中有许多实现
(此实现没有特别优化)
如果您坚持滚动您自己的实现,那么您应该检查的第一件事是,是否仅适用于单个线程。您可以通过将环境变量OMP_NUM_THREADS
设置为1或调用OMP_set_NUM_THREADS(1)来尝试这一点
。如果这样做有效,那么您就知道您的算法是正确的,只是您对OpenMP的使用被破坏了。在检查1个线程的正确性后,假设您正在寻找性能,则在1个线程对其进行优化,继续检查性能。例如,您希望确保内积是simd优化的。对于OpenMP,y除非设置默认值(none),否则不会得到编译器检查private子句的效果。首先,您会错过一个“#pragma omp for”。现在每个线程都在运行整个循环(并且应该得到相同的结果)第二,你在dxi上有一个竞争条件,所以你应该在这个pragma中添加一个reduce子句。这样你就不需要临界段了,因为你可以在平行区域之外执行减法。
int seidel_p(double *A, double *b, double *x, int n)
{
double *dx;
dx = (double*) calloc(n,sizeof(double));
int epsilon = 1.0e-4;
int i,j,k,id;
double dxi;
double sum;
for(int i =0; i<n ; i++)
{
x[i] = 0;
}
int maxit = 2*n*n;
for(k=0; k<maxit; k++)
{
for(i=0; i<n; i++)
{
dx[i] = b[i];
#pragma omp parallel shared(A,x)
{
for(j=0; j<n; j++)
{
if(i!=j)
{
dxi += A[i*n+j]*x[j];
}
}
#pragma omp critical
dx[i] -= dxi;
}
dx[i] /= A[i*n +i];
x[i] = dx[i];
sum += ( (dx[i] >= 0.0) ? dx[i] : -dx[i]);
if(sum<= epsilon) break;
}
}
for( int i = 0 ; i<n ; i++ )
{
printf("\t\t%f\n", dx[i]);
}
free(dx);
}