Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ openmp并行分区_C++_Openmp_Sections - Fatal编程技术网

C++ openmp并行分区

C++ openmp并行分区,c++,openmp,sections,C++,Openmp,Sections,嗨 我正在尝试使用openmp在并行部分运行此代码 我想加快执行速度。可以通过在每个时间步t独立计算这些组。 不幸的是,openmp降低了代码的速度。我一直在寻找并发性,但没有发现任何问题 我正确地使用了sections参数吗 是否有更好的视差框架,我应该使用 祝你一切顺利 #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]

我正在尝试使用openmp在并行部分运行此代码

我想加快执行速度。可以通过在每个时间步t独立计算这些组。 不幸的是,openmp降低了代码的速度。我一直在寻找并发性,但没有发现任何问题

我正确地使用了sections参数吗

是否有更好的视差框架,我应该使用

祝你一切顺利

#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;
            }
        }



    }

}
}

for(t=tIni;t索引变量
i
j
在您的一些节中很常见,这将导致节之间出现同步问题,并且大部分输出不正确。将其更改为使每个节的变量私有
#pragma omp节私有(i,j)
或在每个循环中初始化它们
for(int i=1;iHey,当然这个私有(i,j)是必要的,谢谢你指出。实际上,减速来自其他地方。所有的vort、psi等都是2D数组的两倍。为了避免pragma部分之间的共享并发,我制作了它们的tmp版本(vorttmp,…).但是有了这个新的300x150大小的tmp 2Darray,我的计算机内存过载,执行错误…所以我发现在以静态双vort[Nx][Ny]声明所有数组时我没有上一个问题。但是它会使代码慢10倍!因此我现在已经删除了静态和tmp变量,但获得了一些共享并发性。我不知道
ADI*
方法的实现,但是如果它们都只是读取这些数组而不是修改它们,那么您就不需要创建这些数组的副本。多个thre从公共位置读取ads不会导致并发问题,只有在多个线程向一个位置写入时才会出现并发问题。因此,我建议您不要创建副本。您上次的
omp parallel for
位于
omp parallel sections
块之外,以便在你写回你原来的数组。非常感谢你的澄清。实际上每个ADI函数都写一个2D数组。ADI write vort,ADI_N write N,ADI_C write cO2…它热衷于并发吗?如果ADI
只是修改
vort
ADI_N
只是
N
等等,那么你就不需要同步了nchronize或将任何其他数组作为私有数组或创建副本,因为看起来您的代码在并行部分中不执行任何并发写入。您是否也可以修改问题中的原始代码以突出显示您在何处创建临时数组等…那么,我已经删除了vorttmp等。我没有得到的是至少,使用pragma的代码需要5450秒,而不使用235秒!
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];

    }


}
}