繁体   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