【问题标题】:Optimal datastructure for cudamemcopycudamemcpy 的最优数据结构
【发布时间】:2012-11-30 23:03:43
【问题描述】:

是否存在使用 cudamemcopy(... , devicetohost) 传输数据的最佳数据结构?我发现数组的工作速度比结构快得多。这是有原因的吗,有没有更优化的方法?

编辑-

我的时间似乎没有被正确记录。结构和数组的时间量应该大致相等。我会尝试使用 cuda events api 来记录时间。

【问题讨论】:

  • 只要数据是连续的并且可以使用单个指针进行传输,那么底层数据的排列方式是没有区别的。如果数据不连续但有序,cudaMemcpy2D 可能会有所帮助。单个 cudaMemcpy 调用将所有内容解析为一个指针和该指针之后的字节序列以进行传输。因此,整数数组和结构数组之间应该没有区别,例如,只要总字节数相同。现在,如果结构数组在结构中有填充或其他未使用的空间,那么效率会降低
  • 结构中的数据是连续的。该结构有四个整数和一个浮点数。我将这个结构的数组分配到 gpu 上。我还有一个 5 倍大的数组。我也把它分配到了 gpu 上。当我将内存从 gpu 复制回 cpu 时,比结构具有更多字节的数组传输速度比结构快。所以我的印象是数组可以更快地从内存从设备复制到主机。您是否有任何解决问题的想法可以帮助验证这一点?
  • 您的复制操作计时方法可能有问题。内核调用后的计时操作(例如,从 gpu 到 cpu 的数据的 memcopy)不考虑内核调用立即将控制权返回给主机是一个常见的错误,但是复制操作直到内核运行才开始完全的。请发布(编辑您的问题)一个简单、完整、可编译的示例,以演示时序差异。你是在使用 cuda event api 来做计时吗?
  • 你是对的。我在 linux 中使用 gettimeofday() 函数来获取时间输出。我没有考虑内核执行时间。
  • 如果你只想要合理的复制时间,你可以在你的内核调用之后add a cudaDeviceSynchronize(),在 gettimeofday 检查之前复制之前。但总的来说,如果您使用cuda event api 进行计时,您将不太可能被此绊倒。这很容易。

标签: arrays struct cuda


【解决方案1】:

在内核中将数据从全局内存加载到共享/寄存器时,数组结构通常比结构数组更好。但是,我认为在将数据从主机复制到主机或从设备复制数据时(在一个大的内存复制事务中),SoA 和 AoS 之间没有任何性能差异。毕竟数据量是一样的。

唯一的例外是如果在结构的末尾添加一些额外的填充字节以实现 AoS 元素的某些内存对齐。

我认为您遇到性能差异可能还有其他原因。

【讨论】:

    【解决方案2】:

    就个人而言,我怀疑性能差异是由于副本造成的。

    也许您的数据结构正在以一种有空白的方式对齐。

    第二个原因可能是由于内存页面对齐处理。当您使用 malloc 获取内存时,它可能会像 Windows 文件系统的布局一样被碎片化。碎片化程度可以非常高,但可以说,一次调用malloc得到的内存是连续对齐的,而多次调用得到的内存是有间隙的。

    CUDA 的内存副本必须通过逐页检查页面并手动将它们移动到 GPU 来处理这种额外的开销。


    解决问题的真正方法是使用cudaMallocHost 分配CPU 不必担心的内存。尝试这样做,看看它是否能解决您的问题。

    【讨论】:

      猜你喜欢
      • 2015-10-14
      • 2016-11-24
      • 1970-01-01
      • 1970-01-01
      • 2013-04-21
      • 2011-11-23
      • 1970-01-01
      • 2014-03-30
      相关资源
      最近更新 更多