V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
woshichuanqilz
V2EX  ›  C++

openmp 访问冲突的问题 c++

  •  
  •   woshichuanqilz · 2021-03-07 12:43:53 +08:00 · 1631 次点击
    这是一个创建于 1360 天前的主题,其中的信息可能已经有所发展或是发生改变。

    下面这段代码在运行到, 这个赋值部分的时候会出现访问冲突的问题, 不用 openmp 运行没问题, 我已经加上 critical 关键字了为什么还是有这样的问题? 请问这个问题如何解决? for(m=0;m<nx;m++) { #pragma omp critical img[xpoint[m].wg]+=q1xpoint[m].jx; } for(m=0;m<ny;m++) { #pragma omp critical img[ypoint[m].wg]+=q1ypoint[m].jx; }

    完整代码:

    int i=0,j=0,n=0,m=0; 
        float si=nray/2-0.5; //
        float Cos=0,Sin=0;
        //float tem;
        Point sxy(-RaySource,0);     //射线源初始坐标
        Point sxy_xz;           //旋转后坐标
        Point tcdy_xz[nray];    //探测单元      
        angleSAS(angle);  
    
        float p1=0;
        float p2=0,p3=0,q1=0;
        //for(n=0;n<N_iter;n++)
        Pointwg *xpoint=NULL;
        Pointwg *ypoint=NULL;
        int nx=0,ny=0;
    #pragma omp parallel for num_threads(8) private(xpoint, ypoint, nx, ny)
        for(n=0;n<N_iter;n++)
        {
            s_rec=clock();
            //tem=expf(-2);
    
            //lamda=0.25+0.75*expf(-n);
    
            for(i=0;i<N_angle;i++)
            {			
                Cos=cos(-angle[i]*AngleToPI);
                Sin=sin(-angle[i]*AngleToPI);
                sxy_xz.x=sxy.x*Cos-sxy.y*Sin;
                sxy_xz.y=sxy.x*Sin+sxy.y*Cos;
                for(j=0;j<nray;j++)
                {
                    //tcdy_xz[j].x=(si-j)*Resolution*Cos-detector*Sin; 
                    //tcdy_xz[j].y=(si-j)*Resolution*Sin+detector*Cos;
                    tcdy_xz[j].x=detector*Cos-(si-j)*Resolution*Sin; 
                    tcdy_xz[j].y=detector*Sin+(si-j)*Resolution*Cos;
    #if LSHH
                    nx=0,ny=0;
                    xpoint = NULL;
                    ypoint = NULL;
                    tyxs2(sxy_xz,tcdy_xz[j], &xpoint, &ypoint, &nx, &ny);     //投影系数
                /*	if (nx>513||ny>513||nx<0||ny<0)
                    {
                        cout<<" nx= "<<nx<<" ny="<<ny<<" j= "<<j<<" angle="<<i<<endl;
                    }*/
                    for (m = 0; m < nx; m++) {
                        if (xpoint[m].wg > 512 * 512)
                            cout << xpoint[m].wg << endl;
                    }
    
                    p1=projectdata[i][j];
                    for(m=0;m<nx;m++)
                    {
                        /*if (xpoint[m].wg>(N_img*N_img-1))
                        {
                            cout<<" nx= "<<nx<<" ny="<<ny<<" j= "<<j<<" angle="<<i<<endl;
                            cout<<"m="<<m<<endl;
                            cout<<"射线源:"<<sxy_xz.x<<" "<<sxy_xz.y<<" "<<" 探测器:"<<tcdy_xz[j].x<<" "<<tcdy_xz[j].y<<endl;
                            cout<<"wangge="<<xpoint[m].wg<<endl;
                            cout<<"this is nx"<<endl;
                            getchar();
                        }*/
                        p2+=img[xpoint[m].wg]*xpoint[m].jx;
                        p3+=xpoint[m].jx*xpoint[m].jx;
                    }
                    for(m=0;m<ny;m++)
                    {
                        /*if (ypoint[m].wg>(N_img*N_img-1))
                        {
                            cout<<" nx= "<<nx<<" ny="<<ny<<" j= "<<j<<" angle="<<i<<endl;
                            cout<<"m="<<m<<endl;
                            cout<<"射线源:"<<sxy_xz.x<<" "<<sxy_xz.y<<" "<<" 探测器:"<<tcdy_xz[j].x<<" "<<tcdy_xz[j].y<<endl;
                            cout<<"wangge="<<ypoint[m].wg<<endl;
                            cout<<"this is ny"<<endl;
                            getchar();
                        }*/
                        p2+=img[ypoint[m].wg]*ypoint[m].jx;
                        p3+=ypoint[m].jx*ypoint[m].jx;
                    }
                    q1=(p1-p2)*1.0/p3*lamda;
                    for(m=0;m<nx;m++)
                    {
    #pragma omp critical
                        img[xpoint[m].wg]+=q1*xpoint[m].jx;
                    }
                    for(m=0;m<ny;m++)
                    {
    #pragma omp critical
                        img[ypoint[m].wg]+=q1*ypoint[m].jx;
                    }
    
    #else 
                        tyxs(sxy_xz,tcdy_xz[j]);     //投影系数
                        p1=projectdata[i][j];
                        for(m=0;m<wgjx.size();m++)
                        {
                            p2+=img[wgjx[m].wg]*wgjx[m].jx;
                            p3+=wgjx[m].jx*wgjx[m].jx;
                        }
                        q1=(p1-p2)*1.0/p3*lamda;
                        for(m=0;m<wgjx.size();m++)
                        {
                            img[wgjx[m].wg]+=q1*wgjx[m].jx;
                        }
    #endif
                        p2=0; p3=0; q1=0;
                }
                /*for(m=0;m<N_img*N_img;m++)
                {
                    if(img[m]<0)
                        img[m]=0;
                }*/ //叶片重建,会有负值,直接这样处理,会导致灰度值的丢失,所以,注释掉着一部分*/
            }
            f_rec=clock();
            float t_rec=(float)(f_rec-s_rec)/CLOCKS_PER_SEC;
            cout<<n<<"  "<<t_rec<<endl;
            cout<<"OK"<<endl;
        }
        cout<<"over";
        char size_image[10];
        //itoa(N_img,size_image,10);
        snprintf(size_image, sizeof(size_image), "%d", N_img);
        strcpy(RecData,RecData_temp);
        strcat(RecData,size_image);
    #if LSHH
        strcat(RecData,"Lart");
    #else
        strcat(RecData,"Yart");
    #endif
    
        //strcat(RecData,"art");
        strcat(RecData,".raw");
        write_image(img,RecData,N_img,N_img);
        //加上灰度调整 //
        /*float max,min,diff;
        max=img[0];
        min=img[0];
        for(i=0;i<N_img*N_img;i++)
        {
            if(img[i]>max)
                max=img[i];
            if(img[i]<min)
                min=img[i];		
        }
        diff=1.0/(max-min);
        for(i=0;i<N_img*N_img;i++)
        {
            rec[i]=65535*diff*(img[i]-min);
        }
        FILE *fp;
        fp=fopen(RecData,"wb");
        fwrite(rec,sizeof(unsigned short),N_img*N_img,fp);
        fclose(fp);*/
    
    1 条回复    2021-03-07 14:34:59 +08:00
    chust
        1
    chust  
       2021-03-07 14:34:59 +08:00
    开头定义的一些变量也得声明成 private 吧?或者放到循环里定义,比如 Cos,Sin 那些
    http://jakascorner.com/blog/2016/06/omp-data-sharing-attributes.html
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5370 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 08:25 · PVG 16:25 · LAX 00:25 · JFK 03:25
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.