CUDA统一内存:内存传输行为

3

我正在学习cuda,但目前还没有访问cuda设备,对一些统一内存行为感到好奇。据我所知,统一内存功能根据需要从主机传输数据到设备。因此,如果CPU调用了100次在GPU上的某些数据,则只在第一次尝试时将数据传输到GPU,并清除GPU上的该内存空间。(我的解释是否正确?)

1 假设如此,如果编程结构要适合GPU的内存太大而不能容纳,UM是否会交换一些最近访问的数据结构以腾出空间来完成计算,或者这仍需手动实现?

2 另外,如果您能澄清与内存传输行为相关的另一件事,我将不胜感激。显然,在访问实际数据时,数据将在前后传输,但是访问指针呢?例如,如果我有两个相同UM指针的数组(指针中的数据当前在GPU上,下面的代码从CPU执行),并且要切片第一个数组(可能删除元素),则迭代步骤是否会将指针放入新数组中以便访问数据进行Cudamem传输?肯定不会吧。

1个回答

2
据我所知,统一内存功能是根据需要将数据从主机传输到设备。因此,如果CPU调用了在GPU上的某些数据100次,它只会在第一次尝试时传输数据,并清除GPU上的该内存空间。(到目前为止,我的解释正确吗?)
第一部分是正确的:当CPU尝试访问存储在设备内存中的页面时,它会在主内存中透明地转移。页面在设备内存中的情况可能是实现细节,但我想它可能不会被清除。毕竟,只有在CPU写入页面并且设备再次访问时才需要刷新其内容。最好向NVIDIA的某个人询问。
假设如此,如果编程结构意味着适合于GPU的大小超过了设备内存,那么是否有一些行为可以交换一些最近访问的数据结构,以为下一个完成计算所需的数据腾出空间,还是必须手动完成?
在CUDA 8之前,不行,您不能分配比设备上能容纳的更多(oversubscribe)。自CUDA 8以来,它是可能的:页面在设备内存中发生故障(可能使用LRU策略,但我不确定是否在任何地方指定),这允许处理否则不适合设备并且需要手动流式传输的数据集。
显然,当访问实际数据时,数据将被传输回来,但是访问指针会怎样呢?
它的工作方式完全相同。无论您是解引用由cudaMalloc(甚至malloc)返回的指针还是该数据内的某个指针,驱动程序都会以相同的方式处理它。

也许我上一个问题的示例不是很清楚,我的意思不是释放指针中的内存。例如,有两个具有相同UM指针的数组,但是从第一个数组中,我希望切出一些内容。实际数据并不需要被释放,只是进行了一些指针操作。您是否了解这种行为? - user2255757
我不明白你的评论,我没有提到任何释放内容。 - user703016
抱歉,我对你的回应的可视化表达有些奇怪,但我认为你已经验证了我的想法。在指针操作中,并不会在设备之间引发任何内存传输。 - user2255757
2
我不确定你所说的“玩指针”是什么意思。触发“内存传输”的是页错误,也就是当您对当前物理内存中不存在的地址进行解引用时。将指针作为进行操作不会触发页面错误。 - user703016
超额订阅能力不是取决于CUDA版本,而是取决于计算能力吗?(显然,您需要较新的CUDA版本才能获得最新的计算能力,但仍然如此) - einpoklum
ICBW,但我不认为它与计算能力有关。我猜测这是硬件支持的组合(GPU需要向CPU报告页面错误),以及驱动程序支持(驱动程序需要处理这些页面错误并触发页面迁移)。最好向NVIDIA工程师咨询。 - user703016

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接