下面这段代码在运行到, 这个赋值部分的时候会出现访问冲突的问题, 不用 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);*/
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.