6

我有:

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

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

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

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

4

2 回答 2

3

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

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

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

  • Host <-> Host:由CPU执行(memcpy)
  • 主机 <-> 设备:DMA(设备复制引擎)
  • 设备 <-> 设备:Memcpy CUDA 内核(在 SM 上运行,由驱动程序启动)
于 2012-09-18T10:44:12.757 回答
2

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

于 2012-09-17T08:08:38.923 回答