2011-12-17 65 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