openmp 访问冲突的问题 c++

2021-03-07 12:43:53 +08:00
 woshichuanqilz

下面这段代码在运行到, 这个赋值部分的时候会出现访问冲突的问题, 不用 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);*/
1504 次点击
所在节点    C++
1 条回复
chust
2021-03-07 14:34:59 +08:00
开头定义的一些变量也得声明成 private 吧?或者放到循环里定义,比如 Cos,Sin 那些
http://jakascorner.com/blog/2016/06/omp-data-sharing-attributes.html

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/759254

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX