为什么CUDA固定内存这么快?


83

当我使用固定内存进行CUDA数据传输时,我观察到数据传输速度大大提高。在linux上,实现此目标的底层系统调用是mlock。从mlock的手册页中可以看出,锁定该页可防止将其换出:

mlock()将页面锁定在地址范围内,该地址范围从addr开始并持续len个字节。当调用成功返回时,保证所有包含指定地址范围一部分的页面都驻留在RAM中;

在测试中,我的系统上有几千个可用内存,因此从没有任何风险可以换出内存页面,但我仍然观察到加速。任何人都可以解释这里到底发生了什么吗?任何见解或信息都将不胜感激。


您是否测量了mlock本身的时间?
osgx

不,假定执行mlock调用的实际时间可以忽略不计(如果这就是您要的时间)。真正的开销是实际的数据传输,在我的算法中,这是总循环时间的很大一部分。
Gearoid Murphy

你的CPU是多少?也许,启用了NUMA的节点不会从simple中受益mlock()
osgx 2011年

AMD Phenom(tm)II X4 970处理器
Gearoid Murphy 2011年

Answers:


83

CUDA驱动程序检查内存范围是否被锁定,然后它将使用其他代码路径。锁定的内存存储在物理内存(RAM)中,因此设备可以不需CPU的帮助即可获取它(DMA,又名异步复制;设备仅需要物理页面列表)。非锁定内存可能会在访问时产生页面错误,并且不仅存储在内存中(例如可以交换),因此驱动程序需要访问非锁定内存的每一页,将其复制到固定缓冲区中并传递给它。到DMA(同步,逐页复制)。

如此处所述http://forums.nvidia.com/index.php?showtopic=164661

异步mem复制调用使用的主机内存需要通过cudaMallocHost或cudaHostAlloc进行页面锁定。

我也建议您在developer.download.nvidia.com上查看cudaMemcpyAsync和cudaHostAlloc手册。HostAlloc说,CUDA驱动程序可以检测固定内存:

驱动程序跟踪使用this(cudaHostAlloc)函数分配的虚拟内存范围,并自动加速对诸如cudaMemcpy()之类的函数的调用。


1
我想知道在发出异步复制命令后,让另一个线程尝试对页面进行munlock可以创建多少个havok?
Zan Lynx

1
Zan Lynx,有趣的问题。为什么要解锁此内存?即使在32位PC上,最多可能会锁定2-4 GB的内存,而当PCI Express卡可以访问64位(实际为40或48位)地址时,则可能会更多。购买更多的内存然后购买高度过期的(18k rep!在SO上)编程器要便宜得多。我认为(相信)在Linux中,munlock将被阻止或将返回错误,并且不会破坏系统。
osgx

我可以申请cudaHostRegister指向内存映射文件的指针吗?
Tomilov Anatoliy

15

CUDA使用DMA将固定的内存传输到GPU。可分页的主机内存不能与DMA一起使用,因为它们可能驻留在磁盘上。如果内存未固定(即页面锁定),则首先将其复制到页面锁定的“登台”缓冲区,然后通过DMA复制到GPU。因此,使用固定的内存可以节省从可分页的主机内存复制到分页锁定的主机内存的时间。


5

如果尚未访问内存页面,则可能永远不会将它们交换进来。特别是,新分配的页面将是通用“零页面”的虚拟副本,并且在写入之前没有物理实例。磁盘上的新文件映射将同样仅保留在磁盘上,直到被读取或写入为止。


我认为不是这种情况(我在答案的早期版本中对此进行了介绍),因为它是一个真实的程序,并且程序运行mlock()很快(请查看问题2中的Q)。
osgx 2011年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.