我正在尝试在CUDA中实现一个小项目。初始数据集是:
pos
)data
),必须根据存储在第一个数组中的地址进行访问)res
),它将包含一些计算的结果(对于这个例子,它只会在所有元素中写入值1,以验证数据的一致性。)以下计划:
__global__
void testKernel (unsigned int *res, const unsigned int *data, unsigned int *pos)
{
int idx = blockIdx.x*blockDim.x + threadIdx.x;
int x = pos[idx];
int foo = data[x]; // if I take out this line it works properly
res[idx] = 1;
}
最终在res
数组中编写奇怪的值(类似于data
中存储的值),而不是1.
调用看起来像这样:
#define WIDTH = 500
#define BLK_SIZE = 64
void main() {
int blockSize = BLK_SIZE;
int nBlocks = (WIDTH + BLK_SIZE - 1) / blockSize;
// memory allocations: res[WIDTH]; data[DATA_WIDTH]; pos[WIDTH]
// sanity checks for positions
// H2D memory transfers
testKernel <<<nBlocks,blockSize>>>(res_d, data_d, pos_d);
// D2H memory transfers
// free memory
}
现在我正在使用全局内存,因为我正在努力实现初始实现。内存分配,传输和内核调用都是正确的。
还有其他方法可以正确解决此问题吗?如果是这样,是什么导致了奇怪的结果?
答案 0 :(得分:0)
由于WIDTH
BLK_SIZE
不能被__global__
void testKernel (unsigned int *res, const unsigned int *data, unsigned int *pos)
{
int idx = blockIdx.x*blockDim.x + threadIdx.x;
if (idx < WIDTH) {
...
}
}
分割,您必须在代码中插入if以排除超出范围的indeces:
idx
实际上blockDim
在你的内核中从0到512,以32为块(warp大小),独立于你指定的{{1}}(在这种情况下是多个,所以这不是问题。)