在CUDA中的块之间分配线程

在CUDA中的块之间分配线程,cuda,Cuda,我在CUDA做一个项目。第一次我只使用了一个带有Dim 8*8的块作为矩阵。然后我计算指数如下: int idx = blockIdx.x * blockDim.x + threadIdx.x; int idy = blockIdx.y * blockDim.y + threadIdx.y; 它给了我一个正确的答案。之后,我想在块之间分配线程以测量性能。我使网格变暗为(2,1),块变暗为(4,8) 当我手工调试代码时,它似乎在不更改上述公式的情况下为我提供了正确的索引。但是当我运行程序

我在CUDA做一个项目。第一次我只使用了一个带有
Dim 8*8
的块作为矩阵。然后我计算指数如下:

int idx = blockIdx.x * blockDim.x + threadIdx.x;  
int idy = blockIdx.y * blockDim.y + threadIdx.y;  
它给了我一个正确的答案。之后,我想在块之间分配线程以测量性能。我使网格变暗为(2,1),块变暗为(4,8)

当我手工调试代码时,它似乎在不更改上述公式的情况下为我提供了正确的索引。但是当我运行程序时,屏幕挂起,结果都是零

我做错了什么,我该如何解决

这是内核函数

__global__ void cover_fault(int *a,int *b, int *c, int *d, int *mulFV1, int *mulFV2,     int *checkDalU1, int *checkDalU2, int N)  

 {  
//Fig.2
__shared__ int f[9][9];
__shared__ int compV1[9],compV2[9];
int dalU1[9] , dalU2[9];
int Ra=2 , Ca=2;
for (int i = 0 ; i < N ; i++)
  for (int j = 0 ; j < N ; j++)
         f[i][j]=0;

f[3][0] = 1;
f[0][2] = 1;
f[0][6] = 1;
f[3][7] = 1;
f[2][4] = 1;
f[6][4] = 1;
f[7][1] = 1; 

int t =0 ,A = 1,B = 1 , UTP = 5 , LTP = -5 , U_max = 40 , U_min = -160;
bool flag = true;
int sumV1, sumV2;
int checkZero1 , checkZero2;


int idx = blockIdx.x * blockDim.x + threadIdx.x;  
int idy = blockIdx.y * blockDim.y + threadIdx.y;  

while ( flag == true)
{
    if ( c[idy] == 0 )
            compV1[idy] = 1;

       else if ( c[idy]==1)
                compV1[idy] = 0 ;

       if ( d[idy] == 0 )
            compV2[idy] = 1;

       else if ( d[idy]==1 )
                  compV2[idy] = 0 ;


   sumV1 = reduce ( c, N );
   sumV2 = reduce ( d, N );


   if (idx<N && idy <N)    
    {        
     if(idx==0)                  
          mulFV1[idy]=0;     
     if(idy==0)      
          mulFV2[idx]=0;               

     __syncthreads();     

     atomicAdd(&(mulFV1[idy]),f[idy][idx]*compV2[idx]);     
     atomicAdd(&(mulFV2[idx]),f[idy][idx]*compV1[idy]);   

      } 


    dalU1[idy] = ( -1*A*( sumV1 - Ra )) + (B * mulFV1[idy] * compV1[idy]) ;
    dalU2[idy] = ( -1*A*( sumV2 - Ca )) + (B * mulFV2[idy] * compV2[idy]) ;


    a[idy] = a[idy] + dalU1[idy];
    b[idy] = b[idy] + dalU2[idy];


       if ( a[idy] > U_max )
               a[idy] = U_max;
       else
           if (a[idy] < U_min )
                a[idy] = U_min;

       if ( b[idy] > U_max )
                 b[idy] = U_max;
       else
           if (b[idy] < U_min )
                b[idy] = U_min;


      if (dalU1[idy]==0)
           checkDalU1[idy]=0;
         else
            checkDalU1[idy]=1;

      if (dalU2[idy]==0)
           checkDalU2[idy]=0;
            else
               checkDalU2[idy]=1;

       __syncthreads();     
      checkZero1 = reduce(checkDalU1,N);
      checkZero2 = reduce(checkDalU2,N);

      if ( checkZero1==0 && checkZero2==0)
               flag = false;


      else
      {

       if ( a[idy] > UTP )
              c[idy] = 1;
           else
               if ( a[idy] < LTP )
                      c[idy] = 0 ;

            if ( b[idy] > UTP )
                   d[idy] = 1;
           else
               if ( b[idy] < LTP )
                      d[idy] = 0 ;  

      t++;

      }//end else 
      sumV1=0;
      sumV2=0;
      mulFV1[idy]=0;
      mulFV2[idy]=0;
      } //end while

}//end function
\uuuuuuuuuuuuuuuuuuuuu全局\uuuuuuuuuuuuuuuu无效覆盖层\uuuuuuuuuuuuuuuuu故障(int*a、int*b、int*c、int*d、int*mulFV1、int*mulFV2、int*checkDalU2、int-N)
{  
//图2
__共享_uu_uu_u_u_u_u_u_u_u_u_u_u_u_u_u_u_u_u_u_u;
__共享_uu_uu_uu_uu_u_u_u_u_u_u_u_u_u_u_u_u_u_u_u_u_u;
int-dalU1[9],dalU2[9];
int Ra=2,Ca=2;
对于(int i=0;iUTP)
c[idy]=1;
其他的
if(a[idy]UTP)
d[idy]=1;
其他的
如果(b[idy]
在索引计算中,
idx
将为您提供列索引和行索引。您是否以
M[idy][idx]
的身份访问矩阵


cuda线程按照正交系统组织:X为水平,Y为垂直。因此,如果你说实际矩阵中的点M[0][1],那么它就是M[1][0]。

如果你想得到答案,请发布一些实际代码。否则,您的问题将归结为“我的程序不起作用,为什么?”。你不能指望有人能回答这个问题,是吗?@Talonmes我的代码有300多行,我一直在玩代码,直到我确定问题出在我有超过1个块的时候,大多数代码都是数学语句。@asma-然后删除数学,只需传入和传出数据,直到您得到正确传递数据的多块场景。如果您自己没有发现问题,请发布简化的代码。那么,数学bsck应该很简单。@SteveFallows谢谢你的建议,我对整个代码进行注释,并将上面的索引结果打印出来。索引是对的。@Talonmes:这是一个归约函数,添加行或列的元素。。我从SDK中获得了它,并做了一些修改欢迎Tudor,idx将给我行,idy将给我列。是的,我想访问2D数组,我之前对它进行了测试,并给出了正确的结果。@asma:idx将给出列,而不是行,并对行进行idy。试着扭转它们,看看会发生什么。记住,在一个正交系统上,X是水平轴,Y是垂直轴。我交换了X和Y的索引。但它仍然给了我同样的问题。。hang和zeros:(感谢您的支持,我将在回答中发布我的代码以澄清问题。我通过更改数组的大小和迭代次数来调试我的代码,我发现它在某个点上卡住了,我想是因为内存问题。这是个例外(第一次机会例外在Move.exe 0x75 28 9617:微软C++异常:CUAAYRORGNONEM在内存位置0x00 12F81C…..)有什么想法吗?