我正在学习cuda,但目前还没有访问cuda设备,并对一些统一的内存行为感到好奇。据我所知,统一内存功能,在需要知道的基础上将数据从主机传输到设备。因此,如果cpu调用一些数据100次,那就是在gpu上,它只在第一次尝试时传输数据并清除gpu上的内存空间。 (到目前为止,我的解释是否正确?)
1 假设有这样的行为,如果编程结构意图适合gpu对于设备内存来说太大,那么UM会交换一些最近访问过的数据结构以腾出空间吗?对于需要完成计算的下一个还是必须手动实现?
2 此外,如果您能澄清与内存转移行为相关的其他内容,我将不胜感激。很明显,在访问实际数据时会传回数据,但访问指针又如何呢?例如,如果我有2个相同的UM指针数组(指针中的数据当前在gpu上并且以下代码是从cpu执行的)并且要切片第一个数组,可能要删除一个元素,那么迭代跨过指针放入新数组,以便访问数据进行cudamem传输?肯定不会。
答案 0 :(得分:2)
据我了解,统一内存功能,在需要知道的基础上将数据从主机传输到设备。因此,如果cpu调用一些数据100次,那就是在gpu上,它只在第一次尝试时传输数据并清除gpu上的内存空间。 (到目前为止,我的解释是否正确?)
第一部分是正确的:当CPU试图访问驻留在设备存储器中的页面时,它将透明地传输到主存储器中。设备内存中的页面发生了什么可能是一个实现细节,但我想它可能无法清除。毕竟,其内容只需要刷新如果 CPU写入页面,如果它再次被设备访问。我猜想,最好问一下NVIDIA的人。
假设这样,是否有一些行为,如果编程结构意图适合gpu对于设备内存而言太大,那么UM将交换一些最近访问的数据结构,以便为下一个需要完成的数据结构腾出空间。计算还是必须手动实现?
在CUDA 8之前,不,你不能分配更多(超额订阅)而不是设备上可以容纳的东西。从CUDA 8开始,可能出现以下问题:页面在设备内存中出现故障(可能使用LRU策略,但我不确定是否在任何地方指定),这样就可以处理无法在设备上使用的数据集并需要手动流式传输。
很明显,在访问实际数据时会传回数据,但访问指针又如何呢?
它的工作方式完全相同。您是否取消引用cudaMalloc
(或甚至malloc
)返回的指针,或者中的某些指针该数据没有区别。驱动程序以相同的方式处理它。