我试图实现CUDA文档中给出的prefix-sum(scan)操作的伪代码。我得到的结果是绝对错误的。我修改了我的代码一百次,但仍然遇到了问题。 这是CUDA给出的伪代码:
1: for d = 1 to log2 n do
2: for all k in parallel do
3: if k >= power(2, d) then
4: x[k] = x[k – power(2, d-1)] + x[k]
到目前为止,我编码的CUDA内核是:
// CUDA Kernel
__global__ void
prefixSumCUDA(int *a, size_t n)
{
int tId = threadIdx.x;
for (int offset = 1; offset < n; offset *= 2) {
if (tId >= pow((float)2, offset)) {
int temp = tId - pow((float)2, offset - 1);
a[tId] += a[temp];
}
}
}
如果我在这里犯了任何错误,请告诉我。我知道这个实现很大程度上取决于块和网格的大小。因此,我将在此处提供我的内核调用:
// Kernel launch
prefixSumCUDA << <1, 32 >> > (d_A, n);
输入数组是一个8元素整数类型:
[-] array: 1, 2, 3, 4, 5, 6, 7, 8
CUDA内核的结果如下:
[-] array: 1, 2, 5, 7, 14, 18, 22, 26
提前感谢您的帮助!
答案 0 :(得分:1)
我通过另一种方式实现了这个问题。从0开始而不是1开始偏移更好。这导致以下代码。
__global__ void
prefixSumCUDA(int *a, size_t n)
{
int tId = threadIdx.x;
int end = ceil(log2((float)n));
for (int offset = 0; offset < end; offset++) {
if (tId >= (1 << offset)) {
a[tId] += a[tId - (1 << offset)];
}
}
}