我试图弄清楚CUDA(或OpenCL实现)在我需要固定(页面锁定)内存时是否说的是实话。
我尝试了cudaMallocHost
,并查看了/proc/meminfo
的值Mlocked
和Unevictable
,它们都保持为0,永远不会上升(/proc/<pid>/status
报告VmLck
也为0)。我使用mlock
来分页锁定内存,值如预期的那样上升。
因此,这种行为的两个可能原因可能是:
1.我没有从CUDA API获得页面锁定内存,cudaSuccess是假的
- CUDA绕过了操作系统计数器的页面锁定内存,因为CUDA做了一些魔术与Linux内核
所以真正的问题是:当我使用CUDA分配页锁内存时,为什么我不能从操作系统中获取页锁内存的值?
另外:如果不是从/proc/meminfo
或/proc/<pid>/status
中获取正确的值,那么在哪里可以获得正确的值?
谢谢你,谢谢
系统:Ubuntu 14.04.01 LTS; CUDA 6.5; Nvidida Driver 340.29; Nvidia Tesla K20c
3条答案
按热度按时间voj3qocg1#
看起来CUDA 6.5上的固定分配器正在使用
mmap()
和MAP_FIXED。虽然我不是操作系统Maven,但这显然有“钉住”内存的效果,iidoEe。确保其地址永不改变。然而,这并不是一个完整的解释。请参考@Jeff的回答,他指出了几乎可以肯定的“缺失部分”。让我们考虑一个简短的测试程序:
字符串
如果我们用
strace
运行这个程序,并摘录printf
语句之间的输出部分,我们有:型
(note 1073741824正好是一个千兆字节,即与请求的1048576*1024相同)
查看
mmap
的description,我们有:address给出用于Map的优选起始地址。NULL表示无优先级。该地址上的任何先前Map都将自动删除。除非使用MAP_FIXED标志,否则您给予的地址仍然可以更改。
因此,假设
mmap
命令成功,则所请求的虚拟地址将是固定的,这可能是有用的,但不是全部。正如我所提到的,我不是操作系统Maven,对我来说,这个系统调用究竟会创建一个“固定的”Map/分配并不明显。
MAP_SHARED|MAP_FIXED|MAP_ANONYMOUS
的组合可能以某种方式创建了固定的底层分配,但我没有找到任何证据支持这一点。基于this article,似乎即使
mlock()
-ed页面也无法满足DMA活动的需求,这是CUDA中固定主机页面的关键目标之一。因此,看起来其他东西正在提供实际的“钉扎”(即,保证底层物理页始终驻留在内存中,并且它们的虚拟到物理Map不会改变--后一部分可能由MAP_FIXED
沿着保证底层物理页不会以任何方式移动的任何机制来完成)。这个机制显然没有使用
mlock()
,所以mlock艾德页面在之前和之后都不会改变。然而,我们预计Map统计量会发生变化,如果我们将上述程序产生的out1.txt和out2.txt进行比较,我们会看到(摘录):型
差异大约是一个千兆字节,即请求的“固定”内存量。
n6lpvg4x2#
页面锁定可以有不同的含义。对于用户空间应用程序,这通常意味着将页保留在内存中以避免页错误:
“使用mlock()等调用锁定到内存中的页面必须始终物理存在于系统的RAM中。因此,在表面上,锁定的页面在被应用程序访问时应该永远不会导致页面错误。但是没有什么要求锁定的页面总是出现在同一个地方;如果需要的话,内核可以自由地移动锁定的页面.”[1]
请注意,这些锁定的页面仍然可以移动,并且不适合I/O设备访问。
相反,页面锁定的另一个概念称为固定。固定页保持相同的物理Map。需要此功能的驱动程序通常会直接执行此操作,并绕过锁定页记帐。
cudaMallocHost
几乎肯定会使用cuda驱动程序以这种方式固定页面。更多信息,请参见下面的[1]。
[1][https://lwn.net/Articles/600502/](https://lwn.net/Articles/600502/)
ctehm74n3#
调用os_lock_user_pages来固定页面。
Nvidida驱动程序不计算固定页面。我们无法获取内存的值。