簡體   English   中英

CUDA線程塊中可能是負索引?

[英]Possibly negative indices in a CUDA thread block?

我有一個非常簡單的1D CUDA內核,它做一個包含和的運算,也就是說,如果我們有一個輸入1D數組

[x_0,x_1,x_2,...,x_n-1]

輸出將是

[x_0,x_0 + x_1,x_0 + x_1 + x_2,...,x_0 + x_1 + ... x_n-1]。

下面顯示的內核實際上並沒有完全完成此工作,另一方面,它在每個塊中也完成了它的工作。 無論如何,我的問題不是關於如何完全實現包含和的問題,但是我認為線程計算期間可能存在負索引錯誤。

__global__ void parallel_scan_inefficient(float* input, float* output){
// num_threads and max_i are globalled defined  
__shared__ float temp[num_threads];

int i = blockIdx.x*blockDim.x+threadIdx.x;//global index

if (i<max_i)
{
    temp[threadIdx.x]=input[i];
}

for (unsigned int stride=1;stride<=threadIdx.x; stride*=2)
{
    __syncthreads();
    temp[threadIdx.x]+=temp[threadIdx.x-stride];
}

output[i]=temp[threadIdx.x];

}

該程序實際上來自Hwu&Kirk的教科書“對大規模並行處理器進行編程”,第9章,第203頁。

因此,如您在for循環中所見

for (unsigned int stride=1;stride<=threadIdx.x; stride*=2)
{
    __syncthreads();
    temp[threadIdx.x]+=temp[threadIdx.x-stride];
}

因為每個塊的“ threadIdx.x”都從0開始,而“步距”是從1開始。我們是否看不到例如塊中第一個元素的temp [-1]? 同樣在一次迭代之后,“ stride”然后變為2,我們將看到temp [-2]用於threadIdx.x = 0?

盡管CUDA編譯器沒有報告任何錯誤,但是這對我來說並沒有什么意義-我為此內核運行了cuda-memcheck,但仍然可以。 結果也是正確的(當然,每個塊都是正確的,正如我所說的,該內核僅部分完成了包含和)

我認為我可能犯了一個非常愚蠢的錯誤,但我無法發現它。 任何光將不勝感激。 非常感謝。

如果您有這樣的代碼:

for (unsigned int stride=1;stride<=threadIdx.x; stride*=2)
{
    __syncthreads();
    temp[threadIdx.x]+=temp[threadIdx.x-stride];
}

然后對於threadIdx.x == 0的線程,for循環將被完全跳過。 嘗試在main中運行以下代碼:

for (unsigned int stride=1;stride<=0; stride*=2)
{
    cout << "I am running" << endl;
}

您會看到控制台中沒有任何內容。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM