我正在阅读文档,然后转到第3.2.2章。我看到了cudaMallocPitch()
的定义和解释,并且对访问某些数据成员有些困惑。例如:
int width = 64, height = 64;
float* devPtr;
size_t pitch;
cudaMallocPitch(&devPtr, &pitch,
width * sizeof(float), height);
MyKernel<<<100, 512>>>(devPtr, pitch, width, height);
// Device code
__global__ void MyKernel(float* devPtr,
size_t pitch, int width, int height)
{
for (int r = 0; r < height; ++r) {
float* row = (float*)((char*)devPtr + r * pitch);
for (int c = 0; c < width; ++c) {
float element = row[c];
}
}
}
我不明白为什么MyKernel()第二行的行定义中必须使用char *强制转换。另外,我不明白为什么devPtr是float *。不应该是浮动**吗?
答案 0 :(得分:0)
我不明白为什么需要char *强制转换
因为pitch
是一个以字节为单位的值,并且将指针强制转换为char*
允许将音高作为字节偏移量添加到分配中的行。如果没有强制转换,则偏移量将与原始类型的字节数之比不正确。
为什么devPtr是
float*
。应该不是float**
吗?
不。
节距内存是连续内存的单个分配,由单个指针引用,就像使用malloc
或cudaMalloc
分配的普通内存一样。唯一的特别之处在于它的大小是经过计算的,以便可以将存储在内存中的行数据填充到与GPU上的内存控制器和纹理寻址单元最佳/兼容的长度。这就是在寻址计算中需要间距的原因-间距是所请求的大小,包括必要的填充。