为什么在查找指定内存地址的行时到底需要使用char *强制转换?

时间:2019-05-24 15:17:27

标签: c cuda

我正在阅读文档,然后转到第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 *。不应该是浮动**吗?

1 个答案:

答案 0 :(得分:0)

  

我不明白为什么需要char *强制转换

因为pitch是一个以字节为单位的值,并且将指针强制转换为char*允许将音高作为字节偏移量添加到分配中的行。如果没有强制转换,则偏移量将与原始类型的字节数之比不正确。

  

为什么devPtr是float*。应该不是float**吗?

不。

节距内存是连续内存的单个分配,由单个指针引用,就像使用malloccudaMalloc分配的普通内存一样。唯一的特别之处在于它的大小是经过计算的,以便可以将存储在内存中的行数据填充到与GPU上的内存控制器和纹理寻址单元最佳/兼容的长度。这就是在寻址计算中需要间距的原因-间距是所请求的大小,包括必要的填充。