2011-12-17 67 views
0

我正在CUDA中处理项目。我第一次使用Dim 8*8作为我的矩阵只有一个块。然后我计算了指数如下:在CUDA中分配块之间的线程

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 
+4

如果你想回答发布一些实际的代码。否则你的问题就会变成“我的程序不能工作,为什么?”。你不能真正期望有人能够回答这个问题,对吗? – talonmies 2011-12-17 13:31:16

+0

@talonmies我的代码很长,超过300行,我玩的代码,直到我确定问题是当我有超过1块,大部分的代码是数学语句.. – asma 2011-12-17 15:29:48

+1

@asma - 然后删除数学计算并传入和传出数据,直到您获得多块方案正确传递数据。如果您自己没有发现问题,请发布简化代码。然后把数学bsck应该很简单。 – 2011-12-18 03:20:22

回答

1

在你的指数计算,idx会给你的列索引和idy行索引。您是否以M[idy][idx]访问您的矩阵?

cuda线程根据正交系统组织:X是水平的而Y是垂直的。所以如果你在实际矩阵中说M [0] [1],那么它就是M [1] [0]。

+0

欢迎都铎王朝,idx会给我排和idy会给我列。是的,我想访问二维数组,我测试它之前,给我正确的结果。 – asma 2011-12-17 15:34:09

+0

@asma:idx会给你列,而不是行,并且idy行。试着扭转它们,看看会发生什么。请记住,在正交系统中,X是水平轴,Y是垂直轴。 – Tudor 2011-12-17 15:35:32

+0

我交换X和Y的索引。但它仍然给我同样的问题..挂起和零:( – asma 2011-12-18 15:52:36