我想了解如何将 3 维数组从主机内存复制到设备内存。假设我有一个包含数据的 3d 数组。例如 int host_data[256][256][256]; 我想以这样的方式将该数据复制到 dev_data (设备数组),以便 host_data[x][y][z]=dev_data[x][y][z]; 我该怎么做?我应该如何访问设备中的 dev_data 数组?一个简单的例子会很有帮助。
问问题
4794 次
2 回答
5
常见的方法是展平数组(使其成为一维)。然后,您必须进行一些计算以从(x,y,z)
三元组映射到一个数 - 扁平一维数组中的一个位置。
示例 2D:
int data[256][256];
int *flattened = data;
data[x][y] == fattened[x * 256 + y];
示例 3D:
int data[256][256][256];
int *flattened = data;
data[x][y][z] == flattened[x * 256 * 256 + y * 256 + z];
或使用包装器:
__host__ __device___ inline int index(const int x, const int y, const int z) {
return x * 256 * 256 + y * 256 + z;
}
知道了这一点,您可以像往常一样使用 cudaMalloc 分配一个线性数组,然后使用index
函数访问设备代码中的相应元素。
更新:这个问题 的作者声称已经找到了更好的解决方案(至少对于 2D),您可能想看看。
于 2013-04-03T22:24:10.700 回答
2
对于固定尺寸(例如 [256][256][256]),让编译器为您完成工作并遵循此示例。这很有吸引力,因为我们只需要使用单个指针执行单个 cudaMalloc/cudaMemcpy 来传输数据。如果您必须具有可变尺寸,由于复杂性,最好考虑处理此问题的替代方法,但您可能希望查看此示例(参考我发布的第二个示例代码)。请注意,此方法相当复杂且难以遵循。如果可以避免,我建议不要使用它。
编辑:如果您愿意展平您的阵列,推荐@Ixanezis 提供的答案,并且是常用的。我的回答是基于您确实想在主机和设备上使用 3 个下标访问数组的假设。但是,正如在另一个答案中指出的那样,您可以使用宏或函数模拟 3 个下标访问来计算一维数组的偏移量。
于 2013-04-03T22:26:14.760 回答