【问题标题】:CUDA Copying multiple arrays of structs with cudaMemcpyCUDA 使用 cudaMemcpy 复制多个结构数组
【发布时间】:2013-07-20 15:32:45
【问题描述】:

假设一个结构 X 有一些原语和一个 Y 结构数组:

typedef struct 
{ 
   int a;    
   Y** y;
} X;

X 的实例 X1 在主机上初始化,然后通过 cudaMemcpy 复制到设备内存上的 X 的实例 X2。

这适用于 X 中的所有原语(例如 int a),但 cudaMemcpy 似乎将任何双指针扁平化为单个指针,因此在可以访问 X 中的结构数组的任何地方都会导致越界异常(例如作为 y)。

在这种情况下,我是否应该使用另一个 memcpy 函数,例如 cudaMemcpy2D 或 cudaMemcpyArrayToArray?

非常感谢您的建议。谢谢!

编辑

复制结构数组的自然方法(如“如果它只是 C,我会这样做)是 cudaMalloc 数组,然后 cudaMalloc 并分别初始化每个元素,例如:

X** h_x;
X** d_x;
int num_x;

cudaMalloc((void**)&d_x, sizeof(X)*num_x);

int i=0;
for(;i<num_x;i++)
{
    cudaMalloc((void**)d_x[i], sizeof(X));
    cudaMemcpy(&d_x[i], &h_x[i], sizeof(X), cudaMemcpyHostToDevice);
}

但是,for 的 cudaMalloc 会产生崩溃。我承认我还不习惯在 Cuda 函数中使用指针,所以也许我搞砸了 cudaMalloc 和 cudaMemcpy 参数?

【问题讨论】:

  • CUDA计算能力2.0及以上支持双精度运算,否则编译器会将double转换为float,请注意编译不会出错
  • 我告诉过你,双指针 (**) 使这更具挑战性。如果您想了解如何将** 数组从主机复制到设备,请查看here。这不适合胆小的人。请注意,a.lasram 建议首先在主机上展平。我还建议您接受 a.lasram 给出的答案,如果有新问题,请发布。当您进行批量编辑并在已回答的旧问题中发布大部分新问题时,这会使其他人阅读问题变得混乱和困惑。

标签: c++ c struct cuda memcpy


【解决方案1】:

cudaMemcpycudaMemcpy2DcudaMemcpyArrayToArray 都从主机中的连续内存区域复制到设备上的连续内存区域。

您必须将所有数据复制到发送到设备的中间连续缓冲区中。

【讨论】:

  • 如需更多讨论,您可能对我的回答here 感兴趣。双指针 (**) 更具挑战性。建议您按照 a.lasram 的建议将数据扁平化到一个连续区域。
  • 感谢您的回答。扁平化数据是指将整个结构序列化为字节数组之类的东西吗?
  • @brito 是的,将整个结构序列化为一个连续的字节数组
  • @a.lasram,有没有办法只使用 cudaMallocs 和 cudaMemcpys 复制整个结构?由于所涉及的结构的复杂性,我不愿意进行序列化。我使用我正在尝试解决的代码编辑了原始帖子。谢谢。
  • @brito 也许您误解了 X**、X* 和 X,这就是导致崩溃的原因。请注意,cudaMalloc((void**)&d_x, sizeof(X)*num_x) 分配了 n 次 X* 指针,其中 n=(sizeof(X)*num_x)/sizeof(X*)。保持与主机相同的内存结构不是一个好主意。设备 DRAM 针对高带宽进行了优化,而延迟可能很慢,并且缓存针对在同一扭曲中的高重用进行了优化。分散数据会损害性能。
猜你喜欢
  • 2015-10-14
  • 2011-08-24
  • 2015-06-10
  • 2020-09-19
  • 1970-01-01
  • 1970-01-01
  • 2017-08-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多