我以前不需要在 2 个 GPU 之间存储数据。现在,我猜我会用cudaMemcpy()
和cudaMemcpyDeviceToDevice
标志来做到这一点,但是:
cudaMemcpyDeviceToDevice
标志是否既用于复制单个设备的内存空间内的数据,也用于复制所有设备的内存空间之间的数据?
如果是,
- 如何区分指向不同设备上的内存指针?它是否使用了统一虚拟地址空间机制的细节?
如果是这样的话,那么
- 为什么甚至有 H2D、D2H、D2D 标志用于 cudaMemcpy?它不需要检查它需要解决哪个设备吗?
- 我们不能使用 CUDA 低级驱动程序的
cuGetPointerAttribute()
实现 cudaMemcpy 的无标志版本吗?
对于具有 UVA 效果的设备,您可以使用您描述的机制。 本文档部分可能会引起人们的兴趣(描述设备到设备传输的部分以及有关UVA影响的后续部分(。 否则,有一个可用的cudaMemcpyPeer()
API,其语义略有不同。
如何区分指向不同设备上的内存指针?它是否使用了统一虚拟地址空间机制的细节?
是的,请参阅之前引用的文档部分。
为什么甚至有 H2D、D2H、D2D 标志用于 cudaMemcpy?它不需要检查它需要解决哪个设备吗?
cudaMemcpyDefault
是在 UVA 首次出现时添加的传输标志,以便能够使用通用标记的传输,其中方向由运行时在检查提供的指针时推断
我们不能使用 CUDA 低级驱动程序中的 cuGetPointerAttribute(( 实现 cudaMemcpy 的无标志版本吗?
我假设上面描述的通用标记方法可以满足您的任何需求(或者也许我不明白这个问题(。
这样的讨论可能会产生一个问题:"为什么除了cudaMemcpyDefault
,我还要使用任何东西"?
我能想到使用显式标志的一个可能原因是,如果您提供显式标志,运行时 API 将执行显式错误检查。例如,如果您确定给定的
cudaMemcpy
调用始终位于 H2D 传输方向,则显式使用cudaMemcpyHostToDevice
将导致运行时 API 在提供的指针与指示的方向不匹配时引发错误。你是否重视这样一个概念可能是一个见仁见智的问题。作为不太重要的问题(IMO(,使用显式标志的代码不依赖于UVA的可用性,但这种执行方案在较新的环境中正在"消失">