首页 > 解决方案 > 为什么在查找倾斜内存地址的行时需要 char* 强制转换?

问题描述

我正在阅读文档,并进入第 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 是浮点数*。它不应该是一个浮动**吗?

标签: ccuda

解决方案


我不明白为什么需要 char* 演员表

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

为什么 devPtr 是一个float*. 不应该是一个float**吗?

不。

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


推荐阅读