【发布时间】:2015-09-02 20:20:41
【问题描述】:
我的代码有一个奇怪的问题。如果我尝试在线程内打印某个变量的值,则不会将任何内容写入屏幕,并且所有线程都会在该点停止。这是代码:
#define WINSIZE 1
const int nebsize=(WINSIZE*2+1)*(WINSIZE*2+1);
__global__ void loop(double *img, int *consts, int w, int h, double epsilon){
int ind=blockIdx.x*blockDim.x+threadIdx.x;
if(ind<w*h && !consts[ind] && ind%w>=WINSIZE && ind%w<w-WINSIZE && ind/w>=WINSIZE && ind/w<h-WINSIZE){
int win_inds[nebsize];
double winI[3*(2*WINSIZE+1)*(2*WINSIZE+1)];
double winI_re_aux[3*nebsize];
double pre_win_var[9];
double win_var[9];
double win_mu[3];
double tvals[nebsize*nebsize];
double detwin;
int min_i=ind%w-WINSIZE;
int max_i=ind%w+WINSIZE;
int min_j=ind/w-WINSIZE;
int max_j=ind/w+WINSIZE;
int k;
int l;
k=0;
for(int i=min_i; i<=max_i; i++){
for(int j=min_j; j<=max_j; j++){
win_inds[k]=h*i+j;
k++;
}
}
k=0;
for(int j=min_j; j<=max_j; j++){
l=0;
for(int i=min_i; i<=max_i; i++){
winI[3*(l*(2*WINSIZE+1)+k)]=img[3*(j*w+i)];
winI[3*(l*(2*WINSIZE+1)+k)+1]=img[3*(j*w+i)+1];
winI[3*(l*(2*WINSIZE+1)+k)+2]=img[3*(j*w+i)+2];
l++;
}
k++;
}
win_mu[0]=0;
win_mu[1]=0;
win_mu[2]=0;
for(int i=0; i<nebsize; i++){
win_mu[0]+=winI[3*i];
win_mu[1]+=winI[3*i+1];
win_mu[2]+=winI[3*i+2];
}
win_mu[0]=win_mu[0]/(double)nebsize;
win_mu[1]=win_mu[1]/(double)nebsize;
win_mu[2]=win_mu[2]/(double)nebsize;
//all ok here
//this works here
if(ind==200){
printf("%f\n", win_var[8]);
}
for(int i=0; i<3; i++){
for(int j=0; j<3; j++){
pre_win_var[3*i+j]=0;
for(int n=0; n<nebsize; n++){
pre_win_var[3*i+j]+=winI[3*n+i]*winI[3*n+j];
}
pre_win_var[3*i+j]=pre_win_var[3*i+j]/(double)nebsize;
pre_win_var[3*i+j]+=(i==j)*epsilon/(double)nebsize-win_mu[j]*win_mu[i];
}
}
//this kills all threads
if(ind==200){
printf("%f\n", win_var[8]);
}
detwin=pre_win_var[0]*pre_win_var[4]*pre_win_var[8]+pre_win_var[2]*pre_win_var[3]*pre_win_var[7]+pre_win_var[1]*pre_win_var[5]*pre_win_var[6];
detwin-=pre_win_var[6]*pre_win_var[4]*pre_win_var[2]+pre_win_var[3]*pre_win_var[1]*pre_win_var[8]+pre_win_var[7]*pre_win_var[5]*pre_win_var[0];
win_var[0]=(pre_win_var[4]*pre_win_var[8]-pre_win_var[5]*pre_win_var[7])/detwin;
win_var[3]=-(pre_win_var[3]*pre_win_var[8]-pre_win_var[5]*pre_win_var[6])/detwin;
win_var[6]=(pre_win_var[3]*pre_win_var[7]-pre_win_var[4]*pre_win_var[6])/detwin;
win_var[1]=-(pre_win_var[1]*pre_win_var[8]-pre_win_var[2]*pre_win_var[7])/detwin;
win_var[4]=(pre_win_var[0]*pre_win_var[8]-pre_win_var[2]*pre_win_var[6])/detwin;
win_var[7]=-(pre_win_var[0]*pre_win_var[7]-pre_win_var[1]*pre_win_var[6])/detwin;
win_var[2]=(pre_win_var[1]*pre_win_var[5]-pre_win_var[2]*pre_win_var[4])/detwin;
win_var[5]=-(pre_win_var[0]*pre_win_var[5]-pre_win_var[2]*pre_win_var[3])/detwin;
win_var[8]=(pre_win_var[0]*pre_win_var[4]-pre_win_var[1]*pre_win_var[3])/detwin;
//this line gets executed in all threads if I printf nothing
consts[ind]=666;
}
}
只能在计算值之前打印 win_var 或 pre_win_var 的值,但如果我在此之后尝试打印它们,它似乎会杀死所有线程。如果我什么都不打印,则 consts[ind]=666 行会在所有线程中执行,我知道这一点,因为我可以将 consts 复制回主机内存并打印它。那么,有人知道出了什么问题吗?
【问题讨论】:
-
您的代码中可能存在非法访问权限。由于您的大部分代码活动不会影响任何全局状态,因此编译器会对其进行优化,包括进行非法访问的代码。不知何故,
printf以一种不明显的方式影响编译器优化决策,这影响了哪些代码被丢弃。在您失败的情况下,使用答案here 中描述的方法来确定生成非法访问的确切代码行。投票结束,因为此类问题预计将包括 MCVE -
这就是我得到的:========= CUDA-MEMCHECK ========= 程序命中 cudaErrorLaunchOutOfResources(错误 7),因为“请求启动的资源太多" 关于对 cudaLaunch 的 CUDA API 调用。我想我的内存不足了。
-
@protas:可能没有注册。尝试减小块大小
-
这更有意义。我无法将 printf 直接与代码包含联系起来。但是 printf 肯定会影响寄存器的使用。
-
如果我注释掉 printf 行,错误就会消失。
标签: cuda