C++ Gauss-Seidel使用OpenMP |线性方程组求解

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,除非你有很好的理由自己做这件事,否则不要这样做。有很多库可以做这件事(甚至

我正在使用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,除非你有很好的理由自己做这件事,否则不要这样做。有很多库可以做这件事(甚至更多)。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);
}