我試圖與452591個元素執行一個數組的總和減少,它們都設置爲1,所以總和應452591.這個CUDA總和減少有什麼問題?
我計算線程nThreads
作爲2下一個功率的數量,所以它是524288.在while循環的每次迭代中,只有第一半的線程應該工作,在第i個元素處增加另一半的值。只有在nvalues
上設置的元素數組中的實際值時纔會發生添加。
它適用於127,1025,1072甚至8271個元素。但與452591不同,我可以得到原因。爲452591元的oputput是88064.
__global__ void sum_kernel(int nvalues, double nThreads, double *values)
{ int i = blockIdx.x * blockDim.x + threadIdx.x;
while (nThreads > 1)
{ int middle = nThreads/2;
int j = i + middle;
if (i < middle)
{ if (j < nvalues)
{ values[i] += values[j]; }
else
{ values[i] += 0; }
}
__syncthreads();
nThreads = middle;
}
if (i == 0)
printf("T0 ------> %0.f \n", values[0]);
}
我的猜測是,有時一些theads加0時,他們不應該...也許我會得到錯誤的線程ID?
對於一些詳情我計算的2下一個功率爲:
int expo = ceil(log(n)/log(base));
double next2Pow = (double) pow(base, expo)
內核被稱爲具有1個暗淡塊和MAX_TPB = 1024
爲:
sum_kernel<<< ceil(next2Pow/MAX_TPB), MAX_TPB >>> (nvalues, next2Pow, values_device);
另外,我有檢查並且設備數組中的值是正確的,因爲我可以將它們複製到主機數組中,並在主機中正確獲取總和。
但我想讓內核工作,因爲學習的原因。
我不認爲你理解CUDA執行的本質。 [執行發生在塊](http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#scalable-programming-model),所以你減少全局內存不能工作,因爲'__syncthreads ()'只[在一個塊內同步](http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#synchronization-functions)。如果你想學習如何編寫一個很好的並行縮減,請嘗試[this](http://developer.download.nvidia.com/assets/cuda/files/reduction.pdf),並且有一個cuda縮減示例代碼與它一起。 –
而不是說上面的「不能工作」,我可能應該說「不能保證正常工作的數據集大小大於2048」 –
@RobertCrovella我想在幻燈片35中的例子,但我得到這個錯誤:沒有實例函數模板「warpReduce」與參數列表參數類型匹配的是:(int [],unsigned int) – user3117891