c - 为什么在查找倾斜内存地址的行时需要 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 是浮点数*。它不应该是一个浮动**吗?
解决方案
我不明白为什么需要 char* 演员表
因为pitch
是以字节为单位的值,并且将指针转换为char*
允许将间距添加为分配中行的字节偏移量。如果没有强制转换,则偏移量将与原始类型中的字节数之比不正确。
为什么 devPtr 是一个
float*
. 不应该是一个float**
吗?
不。
Pitched memory 是连续内存的单个分配,由单个指针引用,就像使用malloc
or分配的普通内存一样cudaMalloc
。唯一的特殊之处在于它的大小是经过计算的,以便存储在内存中的逐行数据可以填充到与 GPU 上的内存控制器和纹理寻址单元最佳/兼容的长度。这就是为什么在寻址计算中需要间距——间距是所要求的大小,包括必要的填充。
推荐阅读
- scala - Spark Dataframe:用 StructType 值中的非同质数据类型表示 MapType 的模式
- c# - C# 传递类型(类)方法,如参数
- apache-spark - Zeppelin/Hive/Spark 上的笛卡尔积查询
- laravel - 如何在作业中使用事务或当内存不足时如何在作业中回滚模型写入操作?
- php - 使用正则表达式从文本中删除 URL,当前域除外
- c++ - Boost Spirit x3 -- Parameterizing Parsers with other Parsers
- c++ - 创建 min-cur-max 条形图
- java - 在多个嵌套属性的情况下,Apache Delta 峰值 findBy* 方法的正确语法是什么?
- jquery - Ajax 使用 Django 后端发送 GET,而不是 PUT 和 DELETE
- java - 在 Java 中使用 UDP 广播