在CUDA 4.0编程指南的第21页上,有一个示例(如下所示)来说明在设备存储器中循环2D浮点数组的元素.2D的尺寸是宽度*高度
// 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];
}
}
}
Run Code Online (Sandbox Code Playgroud)
为什么devPtr设备内存指针被强制转换为全局内核函数中的字符指针char*?请有人解释一下这条线.看起来有点奇怪.
这是由于指针算法在C中的工作方式.当您x向指针添加整数时p,它并不总是添加x字节.它增加了x时间sizeof([type that p points to]).
float* row = (float*)((char*)devPtr + r * pitch);
Run Code Online (Sandbox Code Playgroud)
通过强制转换devPtr为a char*,applied(r * pitch*)的偏移量为1字节增量.(因为a char是一个字节).如果没有进行转换,则应用于devPtr的偏移量将是r * pitch 4个字节,因为a float是4个字节.
例如,如果我们有:
float* devPtr = 1000;
int r = 4;
Run Code Online (Sandbox Code Playgroud)
现在,让我们省略演员:
float* result1 = (devPtr + r);
// result1 = devPtr + (r * sizeof(float)) = 1016;
Run Code Online (Sandbox Code Playgroud)
现在,如果我们包括演员:
float* result2 = (float*)((char*)devPtr + r);
// result2 = devPtr + (r * sizeof(char)) = 1004;
Run Code Online (Sandbox Code Playgroud)