openmp的平行部分

时间:2017-12-05 19:31:01

标签: c++ openmp sections

嗨,

我试图用openmp在并行部分运行此代码

我想加快执行速度。这些集团可以在每个时间步 t 独立计算。 不幸的是,代码被openmp放慢了速度。我一直在寻找并发但没有看到任何问题。

我是否正确使用了section参数?

我应该使用更好的parallalisation框架吗?

一切顺利

#define Nx 300
#define Ny 100
int main()
{
int i, j, t=0, it=0;


double vort[Nx][Ny], psi[Nx][Ny], ux[Nx][Ny], uy[Nx][Ny];

double fpsi[Nx][Ny];
double a[Nx][Ny], b[Nx][Ny],c[Nx][Ny], d[Nx][Ny], e[Nx][Ny], ee[Nx][Ny];


//tridiagonal coefficient
//coefficient for the internal grid for vort. Indexed from 0 to Nx-3 or Ny-3 to calculate the interior grid point only. The idix are shiffted of (+1,+1) compare to vort or psi or ux or uy.
//double DDx[Nx-2], AAx[Nx-2], BBx[Nx-2], CCx[Nx-2],    DDy[Ny-2], AAy[Ny-2],BBy[Ny-2], CCy[Ny-2];
double DDx[Nx], AAx[Nx], BBx[Nx], CCx[Nx],    DDy[Ny], AAy[Ny],BBy[Ny], CCy[Ny];
double epsx[Nx][Ny], epsy[Nx][Ny]; //same dimension than ux and uy
//double vortx[Nx-2], vorty[Ny-2];
double vortx[Nx], vorty[Ny];
double cx[Nx][Ny], cy[Nx][Ny]; //same dimension than ux and uy


//coefficient for the ADI
double n[Nx][Ny];
double DDnx[Nx], AAnx[Nx], BBnx[Nx], CCnx[Nx],    DDny[Ny], AAny[Ny],BBny[Ny], CCny[Ny];
double nx[Nx], ny[Ny];

//coefficient for the ADI
double cO2[Nx][Ny];
double DDcx[Nx], AAcx[Nx], BBcx[Nx], CCcx[Nx],    DDcy[Ny], AAcy[Ny],BBcy[Ny], CCcy[Ny];
double cO2x[Nx], cO2y[Ny];

//coefficient for the ADI
double cls[Nx][Ny];
double DDclsx[Nx], AAclsx[Nx], BBclsx[Nx], CCclsx[Nx],    DDclsy[Ny], AAclsy[Ny],BBclsy[Ny], CCclsy[Ny];
double clsx[Nx], clsy[Ny];

//coefficient for the ADI
double pvd[Nx][Ny];
double DDpvdx[Nx], AApvdx[Nx], BBpvdx[Nx], CCpvdx[Nx],    DDpvdy[Ny], AApvdy[Ny],BBpvdy[Ny], CCpvdy[Ny];
double pvdx[Nx], pvdy[Ny];

////代码显示中的差距... ///

for (t=tIni; t<tmax; t++)
    //      for (t=1; t<4; t++)
{

    ///////////////////////////////////////////////////////////////////////////////////////
    //calcul coef upwind differentiation
    ///////////////////////////////////////////////////////////////////////////////////////

    for (j=0; j<Ny; j++)
    {

        for (i=0; i<Nx; i++)
        {
            cx[i][j]=ux[i][j]*DtDx;
            cy[i][j]=uy[i][j]*DtDx;

            if(ux[i][j]>=0)
            {
                epsx[i][j]=1;
            }
            else
            {
                epsx[i][j]=-1;
            }

            if(uy[i][j]>=0)
            {
                epsy[i][j]=1;
            }
            else
            {
                epsy[i][j]=-1;
            }

        }

    }

#pragma omp parallel sections
    {
        ///////////////////////////////////////////////////////////////////////////////////////
        //calcul de la concentration de bacterie
        ///////////////////////////////////////////////////////////////////////////////////////
#pragma omp section
        {
            ADI_N(n, cO2, AAnx, BBnx, CCnx, DDnx, AAny, BBny, CCny, DDny, cx, cy, epsx, epsy, nx, ny, DtDbDxs, Dxs2);
        }
        ///////////////////////////////////////////////////////////////////////////////////////
        //calcul de la concentration d'oxygene
        ///////////////////////////////////////////////////////////////////////////////////////
#pragma omp section
        {
            ADI_C(cO2, n, AAcx, BBcx, CCcx, DDcx, AAcy, BBcy, CCcy, DDcy, cx, cy, epsx, epsy, cO2x, cO2y, DtDO2Dxs, Dxs2, gamma);
        }
        /*for (i=0; i<Nx; i++)
         {
         cO2[i][Ny-1]=1.;
         }*/

        ///////////////////////////////////////////////////////////////////////////////////////
        //calcul de la concentration de cellulose
        ///////////////////////////////////////////////////////////////////////////////////////
#pragma omp section
        {
            ADI_Cls(cls, n, cO2tmp, AAclsx, BBclsx, CCclsx, DDclsx, AAclsy, BBclsy, CCclsy, DDclsy, cx, cy, epsx, epsy, clsx, clsy, DtDclsDxs, Dxs2, Dt*kpvd, seuilCls, seuilStopCls);

        }
        ///////////////////////////////////////////////////////////////////////////////////////
        //calcul de la concentration de poyverdine
        ///////////////////////////////////////////////////////////////////////////////////////
#pragma omp section
        {
            ADI_Pvd(pvd, n, cO2, AApvdx, BBpvdx, CCpvdx, DDpvdx, AApvdy, BBpvdy, CCpvdy, DDpvdy, cx, cy, epsx, epsy, pvdx, pvdy, DtDpvdDxs, Dxs2, Dt*kpvd, seuilCls, seuilStopCls);
        }
        ///////////////////////////////////////////////////////////////////////////////////////
        //calcul de la vorticité
        ///////////////////////////////////////////////////////////////////////////////////////
#pragma omp section
        {

            ADI(vort, psi, n, cls, AAx, BBx, CCx, DDx, AAy, BBy, CCy, DDy, cx, cy, epsx, epsy, vortx, vorty, DtDxsRe, Dxs, coefMass, coefMassCls);
        }

        ///////////////////////////////////////////////////////////////////////////////////////
        //calcul de la stream function
        ///////////////////////////////////////////////////////////////////////////////////////
#pragma omp section
        {
            // Preparation de la force qui agit sur la stream function (potentiel vecteur)
            for (i=0; i<Nx; i++)
            {
                for (j=0; j<Ny; j++)
                {


                    fpsi[i][j]= - vort[i][j]*Dxs; //multiplie par Dxs car les coefficient son multiplie par beta=Dxs/Dys. Donc Dxs est l'unite spatiale.

                    if(isnan(fpsi[i][j]))
                    {
                        cout<<"error psi nan "<<__FILE__<<" line "<<__LINE__<<endl;
                        exit(2);
                    }

                }
            }


            //SOR
            //sorPoissonChebyshev(psi, fpsi, a, b, c, d, e, ee, Nx-1, Ny-1, rjac, it, Nitmax, relax, tol);
            sorPoissonChebyshev(psi, fpsi, a, b, c, d, e, ee, Nx, Ny, rjac, it, relax, Nitmax, tol);

            //condition aux bords. Psi constant sur la frontiere. Mise a zero pour le SOR
            for (i=0; i<Nx; i++)
            {
                psi[i][0]=0;
                psi[i][Ny-1]=0;
            }

            for (j=0; j<Ny; j++)
            {
                psi[0][j]=0;
                psi[Nx-1][j]=0;
            }
        }
            ///////////////////////////////////////////////////////////////////////////////////////
        //calcul de la vitesse
           ///////////////////////////////////////////////////////////////////////////////////////
#pragma omp section
        {
            for (i=1; i<Nx-1; i++)
            {
                for (j=1; j<Ny-1; j++)
                {
                    ux[i][j]=(psi[i][j+1]-psi[i][j-1])/Dx2;
                    uy[i][j]=-(psi[i+1][j]-psi[i-1][j])/Dx2;
                }
            }

            //Boudary conditions
            for (i=0; i<Nx; i++)
            {
                ux[i][Ny-1]=ux[i][Ny-2]; //free slip
                //ux[i][Ny-1]=0; //no slip
                uy[i][Ny-1]=0;

                ux[i][0]=0;
                uy[i][0]=0;
            }
            for (j=0; j<Ny; j++)
            {
                ux[Nx-1][j]=0;
                uy[Nx-1][j]=0;

                ux[0][j]=0;
                uy[0][j]=0;
            }
        }



    }

}
}

---编辑: - 删除tmp - ADI功能

void ADI_N(double n[][Ny], double cO2[][Ny],
       double AAx[], double BBx[], double CCx[], double DDx[],
       double AAy[], double BBy[], double CCy[], double DDy[],
       double cx[][Ny], double cy[][Ny], double epsx[][Ny], double epsy[][Ny],
       double nx[], double ny[], double DbDtDxs, double Dxs2)

{

int i=0, j=0;

for (i=0; i<Nx; i++) //interior points
{
    for (j=0; j<Ny; j++) //interior points
    {
        if (cO2[i][j]>seuilO2) // Seuil en dessous du quel les bacteries ne pousse pas.
        {
            n[i][j]= n[i][j] * ( 1 + Dt /  tempsDeDivBact * cO2[i][j] ); // n et cO2 sont normalizée
        }

    }
}


////////////calcul sur y////////////
//calcul coef ADI


for (i=0; i<Nx; i++) //interior points
{
    for (j=1; j<Ny-1; j++) //interior points
    {

        //non conservative forme
        if (i==0)
        {
            AAy[j] = -.5 * DbDtDxs;

            BBy[j] = 1 + DbDtDxs;

            CCy[j] = - .5 * DbDtDxs;

            DDy[j] = .5 * DbDtDxs * n[1][j]
            + ( 1 - DbDtDxs ) * n[i][j]
            + .5 * DbDtDxs * n[i+1][j];

        }
        else if (i==Nx-1)
        {
            AAy[j] = -.5 * DbDtDxs;

            BBy[j] = 1 + DbDtDxs;

            CCy[j] = - .5 * DbDtDxs;

            DDy[j] = .5 * DbDtDxs * n[i-1][j]
            + ( 1 - DbDtDxs ) * n[i][j]
            + .5 * DbDtDxs * n[Nx-2][j];

        }
        else //conservative forme
        {

             AAy[j] = -.5 * ( .5 * (1 + epsy[i][j]) * cy[i][j-1] + DbDtDxs);

             BBy[j] = 1 + DbDtDxs + .5 * epsy[i][j] * cy[i][j];

             CCy[j] = .5 * ( .5 * ( 1 - epsy[i][j] ) * cy[i][j+1] - DbDtDxs);

             DDy[j] = .5 * (.5 * ( 1 + epsx[i][j] ) * cx[i-1][j] + DbDtDxs ) * n[i-1][j]
             + ( 1 - DbDtDxs - .5 * epsx[i][j] * cx[i][j] ) * n[i][j]
             + .5 * (- .5 * ( 1 - epsx[i][j] ) * cx[i+1][j] + DbDtDxs ) * n[i+1][j];

            /*AAy[j] = -.5 * ( .5 * cy[i][j-1] + DbDtDxs);

            BBy[j] = 1 + DbDtDxs ;

            CCy[j] = .5 * ( .5 * cy[i][j+1] - DbDtDxs);

            DDy[j] = .5 * (.5 * cx[i-1][j] + DbDtDxs ) * n[i-1][j]
            + ( 1 - DbDtDxs ) * n[i][j]
            + .5 * (- .5 * cx[i+1][j] + DbDtDxs ) * n[i+1][j];
            */
        }

        ny[j] = n[i][j];
    }


    //boundary condition values no flux n[i][j-1]=n[i][j+1] and substraction of a[0]*n[i][j] for tridaig calculation.
    //non conservative forme
    if (i==0) {
        j=0; //DDy[j] = DbDtDxs/2 * n[i-1][j] + (1-DbDtDxs) * n[i][j] + DbDtDxs/2 * n[i+1][j] - -( .5 * cy[i][j] + DbDtDxs/2 ) * n[i][j-1];
        DDy[j] = DbDtDxs/2 * n[1][j] + (1-DbDtDxs) * n[i][j] + DbDtDxs/2 * n[i+1][j]
        + DbDtDxs/2 * n[i][1];//AAy
        AAy[j] = 0; // pas utilise soustrait à DDy
        BBy[j] = 1 + DbDtDxs ;
        CCy[j] = .5 * ( .5 * cy[i][j+1] - DbDtDxs);

        j=Ny-1;
        DDy[j] = .5 * ( DbDtDxs + cx[i][j]/2) * n[1][j] + (1-DbDtDxs) * n[i][j] + .5 * ( DbDtDxs - cx[i][j]/2) * n[i+1][j]
        + DbDtDxs/2 * n[i][Ny-2]; //CCy
        AAy[j] = -.5 * ( .5  * cy[i][j] + DbDtDxs);
        BBy[j] = 1 + DbDtDxs;
        CCy[j] = 0; // pas utilise soustrait à DDy
    }
    else if(i==Nx-1)
    { j=0; //DDy[j] = DbDtDxs/2 * n[i-1][j] + (1-DbDtDxs) * n[i][j] + DbDtDxs/2 * n[i+1][j] - -( .5 * cy[i][j] + DbDtDxs/2 ) * n[i][j-1];
        DDy[j] = DbDtDxs/2 * n[i-1][j] + (1-DbDtDxs) * n[i][j] + DbDtDxs/2 * n[Nx-2][j]
        + DbDtDxs/2 * n[i][1];
        AAy[j] = 0; // pas utilise soustrait à DDy
        BBy[j] = 1 + DbDtDxs ;
        CCy[j] = .5 * ( .5 * cy[i][j+1] - DbDtDxs);

        j=Ny-1;
        DDy[j] = .5 * ( DbDtDxs + cx[i][j]/2) * n[i-1][j] + (1-DbDtDxs) * n[i][j] + .5 * ( DbDtDxs - cx[i][j]/2) * n[Nx-2][j]
        + DbDtDxs/2 * n[i][Ny-2];
        AAy[j] = -.5 * ( .5  * cy[i][j] + DbDtDxs);
        BBy[j] = 1 + DbDtDxs;
        CCy[j] = 0; // pas utilise soustrait à DDy
    }
    else
    {
        j=0; //DDy[j] = DbDtDxs/2 * n[i-1][j] + (1-DbDtDxs) * n[i][j] + DbDtDxs/2 * n[i+1][j] - -( .5 * cy[i][j] + DbDtDxs/2 ) * n[i][j-1];
        DDy[j] = DbDtDxs/2 * n[i-1][j] + (1-DbDtDxs) * n[i][j] + DbDtDxs/2 * n[i+1][j]
        + DbDtDxs/2 * n[i][1];
        AAy[j] = 0; // pas utilise soustrait à DDy
        BBy[j] = 1 + DbDtDxs ;
        CCy[j] = .5 * ( .5 * cy[i][j+1] - DbDtDxs);

        j=Ny-1;
        DDy[j] = .5 * ( DbDtDxs + cx[i][j]/2) * n[i-1][j] + (1-DbDtDxs) * n[i][j] + .5 * ( DbDtDxs - cx[i][j]/2) * n[i+1][j]
        + DbDtDxs/2 * n[i][Ny-2];
        AAy[j] = -.5 * ( .5  * cy[i][j] + DbDtDxs);
        BBy[j] = 1 + DbDtDxs;
        CCy[j] = 0; // pas utilise soustrait à DDy

    }



    tridiag_full(AAy, BBy, CCy, DDy, ny, Ny-1); //calcul les point en 0 et en Ny-1 inclus


    for (j=0; j<Ny; j++)
    {
        n[i][j]=ny[j];
    }

}

////////////calcul sur x //////////
//calcul coef ADI
for (j=0; j<Ny; j++)
{


    for (i=1; i<Nx-1; i++)

    {


        //non conservative forme
        if(j==0)
        {

            AAx[i] = -.5 * DbDtDxs;
            BBx[i] = 1 + DbDtDxs;
            CCx[i] = - .5 * DbDtDxs ;

            DDx[i]= .5 * DbDtDxs * n[i][1]
            + ( 1 - DbDtDxs ) * n[i][j]
            + .5 * DbDtDxs * n[i][j+1];
        }

        else if(j==Ny-1)
        {

            AAx[i] = -.5* ( .5 * cx[i][j] + DbDtDxs );
            BBx[i] = 1 + DbDtDxs;
            CCx[i] = .5 * ( .5 * cx[i][j] - DbDtDxs) ;

            DDx[i]= .5 * ( .5 * cy[i][j] + DbDtDxs ) * n[i][j-1]
            + ( 1 - DbDtDxs ) * n[i][j]
            + .5 * ( - .5 * cy[i][j] + DbDtDxs ) * n[i][Ny-2];
        }
        else //conservative forme
        {

             AAx[i] = -.5* ( .5 * ( 1 + epsx[i][j] ) * cx[i-1][j] + DbDtDxs );
             BBx[i] = 1 + DbDtDxs + .5 * epsx[i][j] * cx[i][j];
             CCx[i] = .5 * ( .5 * ( 1 - epsx[i][j] ) * cx[i+1][j] - DbDtDxs) ;

             DDx[i]= .5 * ( .5 * ( 1 + epsy[i][j] ) * cy[i][j-1] + DbDtDxs ) * n[i][j-1]
             + ( 1 - DbDtDxs - .5 * epsy[i][j] * cy[i][j] ) * n[i][j]
             + .5 * (-.5 * ( 1 - epsy[i][j] ) * cy[i][j+1] + DbDtDxs ) * n[i][j+1];


        }


        nx[i]=n[i][j];

    }

    if(j==0)
    {
        i=0;
        AAx[i] = -.5 * DbDtDxs;
        BBx[i] = 1 + DbDtDxs;
        CCx[i] = - .5 * DbDtDxs ;

        DDx[i]= .5 *  DbDtDxs * n[i][1] + ( 1 - DbDtDxs ) * n[i][j] + .5 * DbDtDxs * n[i][j+1]
        -AAx[i];

        i=Nx-1;
        AAx[i] = -.5 * DbDtDxs;
        BBx[i] = 1 + DbDtDxs;
        CCx[i] = - .5 * DbDtDxs ;

        DDx[i]= .5 *  DbDtDxs * n[i][1] + ( 1 - DbDtDxs ) * n[i][j] + .5 * DbDtDxs * n[i][j+1]
        -CCx[i];

    }
    else if(j==Ny-1)
    {
        i=0;
        AAx[i] = -.5 * ( .5 * cx[i][j] + DbDtDxs);
        BBx[i] = 1 + DbDtDxs;
        CCx[i] = .5 * (.5 * cx[i][j] - DbDtDxs );

        DDx[i]= .5 *  DbDtDxs * n[i][j-1] + ( 1 - DbDtDxs ) * n[i][j] + .5 * DbDtDxs * n[i][Ny-2]
        -AAx[i];

        i=Nx-1;
        AAx[i] = -.5 * ( .5 * cx[i][j] + DbDtDxs);
        BBx[i] = 1 + DbDtDxs;
        CCx[i] = .5 * (.5 * cx[i][j] - DbDtDxs );

        DDx[i]= .5 *  DbDtDxs * n[i][j-1] + ( 1 - DbDtDxs ) * n[i][j] + .5 * DbDtDxs * n[i][Ny-2]
        -CCx[i];

    }
    else
    {
        i=0;
        AAx[i] = -.5 * DbDtDxs;
        BBx[i] = 1 + DbDtDxs;
        CCx[i] = - .5 * DbDtDxs ;

        DDx[i]= .5 *  DbDtDxs * n[i][j-1] + ( 1 - DbDtDxs ) * n[i][j] + .5 * DbDtDxs * n[i][j+1]
        -AAx[i];

        i=Nx-1;
        AAx[i] = -.5 * DbDtDxs;
        BBx[i] = 1 + DbDtDxs;
        CCx[i] = - .5 * DbDtDxs ;

        DDx[i]= .5 *  DbDtDxs * n[i][j-1] + ( 1 - DbDtDxs ) * n[i][j] + .5 * DbDtDxs * n[i][j+1]
        -CCx[i];

    }


    //boundary condition values no flux n[i-1][j]=n[i+1][j] and substraction of a[0]*n[i][j] for tridaig calculation.
    i=0;
    DDx[i] = (1-DbDtDxs) * n[i][j] + 3*DbDtDxs/2 * n[i+1][j];
    AAx[i] = 0 ; //pas utlise soustrait à DDx
    BBx[i] = 1 + DbDtDxs ;
    CCx[i] = - .5 * DbDtDxs ;

    i=Nx-1;
    DDx[i] = 3*DbDtDxs/2 * n[i-1][j] + (1-DbDtDxs) * n[i][j];
    AAx[i] = - .5* DbDtDxs;
    BBx[i] = 1 + DbDtDxs ;
    CCx[i] = 0 ; //pas utlise soustrait à DDx


    tridiag_full(AAx, BBx, CCx, DDx, nx, Nx-1); //calcul les point en 0 et en Nx-1 inclus

    for (i=0; i<Nx; i++)
    {
        n[i][j]=nx[i];

    }


}
}

1 个答案:

答案 0 :(得分:1)

索引变量i&amp; j在您的某些部分中很常见,这会导致部分之间出现同步问题,而且大多数输出​​不正确。将其更改为为每个部分#pragma omp section private(i,j)设置变量私有,或者在每个循环for (int i=1; i<Nx-1; i++)中初始化变量。我总是喜欢在我的循环中初始化变量,因为我不会意外地重用上一次迭代中的陈旧值。