2015-09-02 29 views
0

我的代码有一个奇怪的问题。如果我尝试在线程内打印某个变量的值,则不会将任何内容写入屏幕,并且所有线程在该点停止。下面是代码:在cuda中打印__global__函数杀死线程

#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复制回主机内存并打印出来。那么,任何人都知道什么是错的?

+1

您的代码中可能存在非法访问。由于大部分代码活动不会影响任何全局状态,编译器会优化它,包括执行非法访问的代码。不知何故,'printf'以非显而易见的方式影响着编译器优化决策,影响了哪些代码被抛弃。在失败的案例中使用回答[here](http://stackoverflow.com/questions/27277365)中描述的方法来识别生成非法访问的确切代码行。投票结束,因为这样的问题预计将包括一个MCVE –

+0

这就是我得到的:========= CUDA-MEMCHECK =========程序命中cudaErrorLaunchOutOfResources(错误7)由于在CUDA API调用cudaLaunch时,“请求启动的资源太多”。我想我已经不在了。 – protas

+0

@protas:可能超出寄存器范围。尝试减小块大小 – talonmies

回答

1

该问题似乎是资源枯竭之一。由于包含ABI调用的内核的寄存器占位面积较大,启用cudaErrorLaunchOutOfResources时启用了printf

您没有提供有关启动参数的任何细节,但将每个块的总线程数减少到32的较小倍数应该可以解决问题。

+0

更好的是,线程的数量是32的倍数还是块的数量是GPU中多处理器数量的倍数?我试图根据输入图像的像素数量和GPU上的多处理器数量来计算执行时间的块数和线程数。 – protas

+1

两者都是理想的。但是,每个块的线程是变形尺寸的倍数是最重要的。 – talonmies