【问题标题】:Better or the same: CPU memcpy() vs device cudaMemcpy() on pinned, mapped memory in CUDA?更好还是相同:CPU memcpy() 与设备 cudaMemcpy() 在 CUDA 中的固定映射内存上?
【发布时间】:2012-09-17 05:42:55
【问题描述】:

我有:

  • 已使用cudaHostAlloc(..., cudaHostAllocMapped)cudaHostRegister(..., cudaHostRegisterMapped) 成功固定和映射的主机内存;
  • 已使用cudaHostGetDevicePointer(...) 获取设备指针。

我在 src 和 dest 设备指针上启动cudaMemcpy(..., cudaMemcpyDeviceToDevice),这些指针指向通过上述技术获得的两个不同的固定+映射内存区域。 一切正常。

问题:我应该继续这样做还是只使用传统的 CPU 风格的memcpy(),因为一切都在系统内存中? ...或者它们是相同(即,当 src 和 dest 都被固定时,cudaMemcpy 是否映射到直接的 memcpy)?

(我仍在使用cudaMemcpy 方法,因为以前所有内容都在设备全局内存中,但由于 gmem 大小限制,后来切换到固定内存)

【问题讨论】:

  • 这是一个有趣的问题。如果您使用优化的 memcpy,CPU 可能会更好 - 毕竟内存属于它 - 并且离散 GPU 执行 host->host memcpy 的能力仅限于 PCIe 带宽。但如果 GPU 会闲置,为什么不呢?
  • 我希望 GPU 不会进行复制。我希望运行时会看到指针都是主机指针并调用主机 memcpy。我已要求了解实际发生的情况。

标签: cuda memcpy


【解决方案1】:

使用cudaMemcpy,CUDA 驱动程序检测到您正在从主机指针复制到主机指针,并且复制在 CPU 上完成。如果您愿意,当然可以自己在 CPU 上使用 memcpy。

如果您使用cudaMemcpy,则在进行复制之前可能会执行额外的流同步(您可能会在分析器中看到,但我猜在那里——测试并查看)。

在 UVA 系统上,您可以使用 cudaMemcpyDefault,正如 talonmies 在他的回答中所说的那样。但如果您没有 UVA(sm_20+ 和 64 位操作系统),那么您必须调用正确的副本(例如 cudaMemcpyDeviceToDevice)。如果您 cudaHostRegister() 对您感兴趣的所有内容,那么 cudaMemcpyDeviceToDevice 最终会根据内存所在的位置执行以下操作:

  • 主机主机:由CPU执行(memcpy)
  • 主机 设备:DMA(设备复制引擎)
  • 设备 设备:Memcpy CUDA 内核(在 SM 上运行,由驱动程序启动)

【讨论】:

  • 非常有趣,您有找到信息的来源吗?
  • 我相信我向我的 NVIDIA 同事询问了实施细节。
【解决方案2】:

如果您在使用 UVA(统一虚拟寻址)的平台上工作,我强烈建议您使用 cudaMemcpycudaMemcpyDefault。这样一来,所有关于最快路径的手动操作都变成了您不必担心的内部 API 实现细节。

【讨论】:

  • 是也不是,我经常在 C1060 上工作,但可以使用 C2050/70。那么,关于我的固定记忆问题,你知道cudaMemcpyDefault 在这种情况下在幕后做了什么吗?这几乎可以回答这个问题。
  • 我不工作。对于 NVIDIA,所以我没有看到任何代码,但它似乎查看了源指针和目标指针并相应地查看。您将获得带有主机指针的主机端副本和带有设备指针的设备到设备副本
猜你喜欢
  • 2013-10-16
  • 2011-02-08
  • 2014-06-05
  • 2013-05-01
  • 1970-01-01
  • 2012-09-11
  • 2011-02-25
  • 2011-10-25
  • 1970-01-01
相关资源
最近更新 更多