CUDA:如何将3D阵列从主机复制到设备?

时间:2013-04-03 22:07:13

标签: arrays 3d cuda memcpy

我想学习如何将3维数组从主机内存复制到设备内存。 假设我有一个包含数据的3d数组。例如 int host_data [256] [256] [256]; 我想以这种方式将该数据复制到dev_data(设备数组) HOST_DATA [X] [Y] [Z] = dev_data [X] [Y] [Z]; 我该怎么做?以及如何访问设备中的dev_data数组? 一个简单的例子非常有用。

2 个答案:

答案 0 :(得分: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函数访问设备代码中的相应元素。

<强>更新 this question的作者声称找到了更好的解决方案(至少对于2D),你可能想看看。

答案 1 :(得分:2)

对于固定尺寸(例如[256] [256] [256]),让编译器为您完成工作并遵循this example。这很有吸引力,因为我们只需要使用单个指针来执行单个cudaMalloc / cudaMemcpy来传输数据。如果您必须具有可变维度,最好考虑由于复杂性而处理此问题的其他方法,但您可能希望查看this example(参考我发布的第二个示例代码)。请注意,这种方法要复杂得多,难以遵循。如果可以避免,我建议不要使用它。

编辑:如果您愿意压扁阵列,建议使用@Ixanezis提供的答案,这是常用的。我的答案基于这样的假设,即您确实希望在主机和设备上使用3个下标来访问阵列。然而,正如在另一个答案中指出的那样,您可以使用宏或函数模拟3个下标访问,以计算1-D数组的偏移量。