c++ - 在设备上的线性内存中循环二维数组时将 float* 转换为 char*

标签 c++ pointers cuda

在 CUDA 4.0 编程指南的第 21 页有一个示例(下面给出)来说明循环遍历 设备内存中二维 float 组的元素。 2D的尺寸是width*height

// Host code
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];
              }
     }
}

为什么 devPtr 设备内存指针在 global 内核函数中被强制转换为字符指针 char*?有人可以解释一下那条线吗?看起来有点奇怪。

最佳答案

这是由于方式pointer arithmetic在 C 中工作。当您将整数 x 添加到指针 p 时,它并不总是添加 x 字节。它增加了 xsizeof(*p)(p 指向的对象的大小)。

float* row = (float*)((char*)devPtr + r * pitch);

通过将 devPtr 转换为 char*,应用的偏移量 (r * pitch*) 为 1 字节数增量。 (因为 char 是一个字节)。如果转换不存在,应用于 devPtr 的偏移量将是 r * pitch 乘以 4 字节,因为 float 是四个字节。

例如,如果我们有:

float* devPtr = 1000;
int r = 4;

现在,让我们忽略类型转换:

float* result1 = (devPtr + r);
// result1 = devPtr + (r * sizeof(float)) = 1016;

现在,如果我们包括类型转换:

float* result2 = (float*)((char*)devPtr + r);
// result2 = devPtr + (r * sizeof(char)) = 1004;

关于c++ - 在设备上的线性内存中循环二维数组时将 float* 转换为 char*,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8772172/

相关文章:

c++ - C++ 编译器中的 POD 和 VPtr 设计

c++ - 启用 OpenCV cuda 的构建不起作用

c++ - 在带有 libstdc++ 的 Linux 上使用 -fsanitize=memory 和 clang

c - 将指针传递给列表、函数

c++ - 如何从 std 字符串 (c_str()) 设置 char * 值不起作用

C#:指向空数组的不安全指针为空?

cuda - 为什么CUDA编译器内部函数__fadd_rd等对我不起作用?

c++ - cudaMemcpyToSymbol 使用或不使用字符串

C++ 读取文件

c++ - 如何使用 "conflicting types"解决 C++/C 编译期间的 `python setup.py build` 错误?