2016-08-13 58 views
0

我試圖在cuda中實現減少,在那裏我找到了數組中的最大元素。我已經使用這個內核來尋找最小值,並且它可以工作,但是當我試圖找到最大值時它不起作用。我已經重複了這個算法,找不到錯誤。任何幫助真的會被讚賞。 (另外,我得到不同的結果,當我取消打印語句出現,這也是頗爲頭疼....)在CUDA中實現減少的問題

__global__ 
void findMaxAndMin(const float* const d_logLuminance, float* reduceCopy, int length, float* min_logLum, float* max_logLum){ 
    int idx = threadIdx.x + blockDim.x*blockIdx.x; 
    if(idx >= length){ 
     return; 
    } 
    reduceCopy[idx] = d_logLuminance[idx]; 
    __syncthreads(); 

    //do a reduction with max 

    for(int offset = 1;offset < length;offset = offset*2){ 
     if(idx % (offset*2) == 0){ 
      int compIdx = idx + offset; 
      if(compIdx < length){ 
       float newVal = a_max(reduceCopy[idx], reduceCopy[compIdx]); 
       if(idx == 0){ 
        //printf("val %f \n", newVal); 
       } 
       __syncthreads(); 
       reduceCopy[idx] = newVal; 
       __syncthreads(); 
      } 
     } 
     __syncthreads(); 
    } 
    __syncthreads(); 
    if(idx == 0){ 
     *max_logLum = reduceCopy[0]; 
    } 

} 

回答

1

有幾個問題的代碼。如果它工作的最低限度,你很幸運。

  • 我推測你啓動了多個塊(使用blockIdx.x)。您重複使用另一個塊的結果 - reduceCopy[compIdx]可能由另一個塊設置。你不能依靠這個:你不能預測塊的執行順序或同步它們。 __syncthreads()是一個障礙,只能在一個塊內工作!

  • if(idx >= length) return是危險的,因爲它會導致並非所有線程都會達到以下__syncthreads

  • 你有__syncthreads()在不同的條件if(compIdx < length)內。

  • a_max未定義。請記住始終包含最低工作示例。我可以猜測這個函數應該做什麼,但是可能還有另一個潛伏的bug?

在我看來,你對理論上的並行簡化有很好的理解,但是由於CUDA特定的行爲,實現失敗。

我建議你閱讀一些關於如何在CUDA上專門進行並行壓縮的例子。

+0

非常感謝你,我不知道一些這種cuda的具體行爲...我會盡力重新實現這一點。謝謝! –