1

我想了解如何将 3 维数组从主机内存复制到设备内存。假设我有一个包含数据的 3d 数组。例如 int host_data[256][256][256]; 我想以这样的方式将该数据复制到 dev_data (设备数组),以便 host_data[x][y][z]=dev_data[x][y][z]; 我该怎么做?我应该如何访问设备中的 dev_data 数组?一个简单的例子会很有帮助。

4

2 回答 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 回答