2012-03-29 69 views
3

我遇到了一些嵌套循環的問題,我必須從C/C++轉換爲CUDA。基本上我有4個嵌套循環,它們共享相同的數組並進行位移操作。對於使用CUDA的嵌套循環

#define N 65536 

// ---------------------------------------------------------------------------------- 

int a1,a2,a3,a4, i1,i2,i3,i4; 

int Bit4CBitmapLookUp[16] = {0, 1, 3, 3, 7, 7, 7, 7, 15, 15, 15, 15, 15, 15, 15, 15}; 

int _cBitmapLookupTable[N]; 

int s = 0; // index into the cBitmapLookupTable 

for (i1 = 0; i1 < 16; i1++) 
{ 
    // first customer 
    a1 = Bit4CBitmapLookUp[i1] << 12; 

    for (i2 = 0; i2 < 16; i2++) 
    { 
     // second customer 
     a2 = Bit4CBitmapLookUp[i2] << 8; 

     for (i3 = 0; i3 < 16; i3++) 
     { 
      // third customer 
      a3 = Bit4CBitmapLookUp[i3] << 4; 

      for (i4 = 0;i4 < 16;i4++) 
      { 
       // fourth customer 
       a4 = Bit4CBitmapLookUp[i4]; 

       // now actually set the sBitmapLookupTable value 
       _cBitmapLookupTable[s] = a1 | a2 | a3 | a4; 

       s++; 

      } // for i4 
     } // for i3 
    } // for i2 
} // for i1 

這是我應該轉換成CUDA的代碼。我嘗試了不同的方式,但每次輸錯都是錯誤的。這裏我發表我的版本CUDA轉換(片從內核的一部分)

#define N 16 

//---------------------------------------------------------------------------------- 

// index for the GPU 
int i1 = blockDim.x * blockIdx.x + threadIdx.x; 
int i2 = blockDim.y * blockIdx.y + threadIdx.y; 
int i3 = i1; 
int i4 = i2; 

__syncthreads(); 
for(i1 = i2 = 0; i1 < N, i2 < N; i1++, i2++) 
{ 
    // first customer 
    a1 = Bit4CBitmapLookUp_device[i1] << 12; 

    // second customer 
    a2 = Bit4CBitmapLookUp_device[i2] << 8; 

    for(i3 = i4 = 0; i3 < N, i4 < N; i3++, i4++){ 
     // third customer 
     a3 = Bit4CBitmapLookUp_device[i3] << 4; 

     // fourth customer 
     a4 = Bit4CBitmapLookUp_device[i4]; 

     // now actually set the sBitmapLookupTable value 
     _cBitmapLookupTable[s] = a1 | a2 | a3 | a4; 
     s++; 
    } 
} 

的我在CUDA全新的,我還在學習,但我真的無法找到那些嵌套循環的解決方案。 預先感謝您。

+1

提示:您正在將變量'i1' ...'i4'初始化爲永遠不會使用的值。 – leftaroundabout 2012-03-29 09:15:20

+0

請參閱本 - > http://stackoverflow.com/questions/5306117/cuda-kernel-nested-for-loop http://stackoverflow.com/questions/6479715/nested-loops-to-cuda http://stackoverflow.com/questions/9527026/cumulative-sum-in-two-dimensions-on-array-in-nested-loop-cuda-implementation – 2012-03-29 09:29:31

回答

2

由於左邊已經指出初始化存在問題。我建議是,你重寫程序如下

int i1 = blockDim.x * blockIdx.x + threadIdx.x; 
int i2 = blockDim.y * blockIdx.y + threadIdx.y; 
int i3; 
int i4; 

while(i1 < N && i2 < N){ 
    a1 = ..; 
    a2 = ..; 
    for(i3 = i4 = 0; i3 < N, i4 < N; i3++, i4++){ 
    // third customer 
    a3 = Bit4CBitmapLookUp_device[i3] << 4; 

    // fourth customer 
    a4 = Bit4CBitmapLookUp_device[i4]; 

    // now actually set the sBitmapLookupTable value 
    _cBitmapLookupTable[s] = a1 | a2 | a3 | a4; 
    s ++; 
    } 
    s += blockDim.x*gridDim.x*blockDim.y*gridDim.y; 
    i1 += blockDim.x*gridDim.x; 
    i2 += blockDim.y*gridDim.y; 
} 

我沒有測試過,所以我不能保證指數是正確的。我會把它留給你。

更多解釋:在上面的代碼中,只有i1和i2上的循環被並行化。這假設N ** 2與GPU上的核心數量相比足夠大。如果情況並非如此。所有四個循環都需要進行並行處理以獲得高效的程序。這種做法會有所不同。

+0

但是,這個指標I3和I4?我應該將它們聲明爲正常整數嗎? – davideberdin 2012-03-29 12:14:42

+0

對不起,我認爲很明顯他們被認爲是正常的整數。更新了我的答案。 – Azrael3000 2012-03-29 12:23:41