CUDA和固定(页面locking)内存不是页面locking?

我试图弄清楚CUDA(或OpenCL实现)是否在需要固定(页面locking)的内存时说实话。

我试着cudaMallocHost并看着/proc/meminfoMlockedUnevictable ,都停留在0,永远不会( /proc/<pid>/status报告VmLck也为0)。 我用mlock来locking页面内存,并按照预期值上升。

所以这种行为的两个可能的原因可能是:

  1. 我没有从CUDA API获取页面locking内存,并且cudaSuccess是假的
  2. CUDA绕过了页面locking内存的操作系统计数器,因为CUDA在Linux内核方面有一些神奇的function

所以实际的问题是:当我使用CUDA分配页面locking内存时,为什么我无法从操作系统获取页面locking内存的值?

另外:如果不是从/proc/meminfo/proc/<pid>/status我可以在哪里得到正确的值?

谢谢!

系统:Ubuntu 14.04.01 LTS; CUDA 6.5; Nvidida Driver 340.29; Nvidia Tesla K20c

看起来CUDA 6.5上的固定分配器使用mmap()和MAP_FIXED。 虽然我不是操作系统专家,但我相信这会产生“固定”内存的效果,即确保其地址永不改变。

我们来考虑一个简短的测试程序:

 #include <stdio.h> #define DSIZE (1048576*1024) int main(){ int *data; cudaFree(0); system("cat /proc/meminfo > out1.txt"); printf("*$*before alloc\n"); cudaHostAlloc(&data, DSIZE, cudaHostAllocDefault); printf("*$*after alloc\n"); system("cat /proc/meminfo > out2.txt"); cudaFreeHost(data); system("cat /proc/meminfo > out3.txt"); return 0; } 

如果我们用strace运行这个程序,并且在printf语句之间的输出部分,我们有:

 write(1, "*$*before alloc\n", 16*$*before alloc) = 16 mmap(0x204500000, 1073741824, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED|MAP_ANONYMOUS, 0, 0) = 0x204500000 ioctl(11, 0xc0304627, 0x7fffcf72cce0) = 0 ioctl(3, 0xc0384657, 0x7fffcf72cd70) = 0 write(1, "*$*after alloc\n", 15*$*after alloc) = 15 

(注意,1073741824正好是1千兆字节,即与请求的1048576 * 1024相同)

回顾mmap的描述 ,我们有:

地址给出映射的首选起始地址。 NULL表示没有偏好。 在该地址的任何以前的映射会自动删除。 您提供的地址可能仍会更改,除非您使用MAP_FIXED标志。

因此,假设mmap命令成功,请求的内存地址将被固定,因此内存被“固定”。

这个机制显然不使用mlock() ,所以mlock()的页面在之前和之后都不会改变。 但是,我们希望映射统计信息发生变化,如果我们对由上述程序生成的out1.txt和out2.txt进行比较,我们可以看到(摘录):

 < Mapped: 87488 kB --- > Mapped: 1135904 kB 

差异大约是一个千兆字节,即所请求的“固定”内存量。