linux CUDA和固定(页面锁定)内存根本没有页面锁定?

pkwftd7m  于 2023-08-03  发布在  Linux
关注(0)|答案(3)|浏览(108)

我试图弄清楚CUDA(或OpenCL实现)在我需要固定(页面锁定)内存时是否说的是实话。
我尝试了cudaMallocHost,并查看了/proc/meminfo的值MlockedUnevictable,它们都保持为0,永远不会上升(/proc/<pid>/status报告VmLck也为0)。我使用mlock来分页锁定内存,值如预期的那样上升。
因此,这种行为的两个可能原因可能是:
1.我没有从CUDA API获得页面锁定内存,cudaSuccess是假的

  1. CUDA绕过了操作系统计数器的页面锁定内存,因为CUDA做了一些魔术与Linux内核
    所以真正的问题是:当我使用CUDA分配页锁内存时,为什么我不能从操作系统中获取页锁内存的值?
    另外:如果不是从/proc/meminfo/proc/<pid>/status中获取正确的值,那么在哪里可以获得正确的值?
    谢谢你,谢谢
    系统:Ubuntu 14.04.01 LTS; CUDA 6.5; Nvidida Driver 340.29; Nvidia Tesla K20c
voj3qocg

voj3qocg1#

看起来CUDA 6.5上的固定分配器正在使用mmap()和MAP_FIXED。虽然我不是操作系统Maven,但这显然有“钉住”内存的效果,iidoEe。确保其地址永不改变。然而,这并不是一个完整的解释。请参考@Jeff的回答,他指出了几乎可以肯定的“缺失部分”。
让我们考虑一个简短的测试程序:

#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


(note 1073741824正好是一个千兆字节,即与请求的1048576*1024相同)
查看mmapdescription,我们有:
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进行比较,我们会看到(摘录):

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


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

n6lpvg4x

n6lpvg4x2#

页面锁定可以有不同的含义。对于用户空间应用程序,这通常意味着将页保留在内存中以避免页错误:
“使用mlock()等调用锁定到内存中的页面必须始终物理存在于系统的RAM中。因此,在表面上,锁定的页面在被应用程序访问时应该永远不会导致页面错误。但是没有什么要求锁定的页面总是出现在同一个地方;如果需要的话,内核可以自由地移动锁定的页面.”[1]
请注意,这些锁定的页面仍然可以移动,并且不适合I/O设备访问。
相反,页面锁定的另一个概念称为固定。固定页保持相同的物理Map。需要此功能的驱动程序通常会直接执行此操作,并绕过锁定页记帐。cudaMallocHost几乎肯定会使用cuda驱动程序以这种方式固定页面。
更多信息,请参见下面的[1]。
[1][https://lwn.net/Articles/600502/](https://lwn.net/Articles/600502/)

ctehm74n

ctehm74n3#

调用os_lock_user_pages来固定页面。
Nvidida驱动程序不计算固定页面。我们无法获取内存的值。

相关问题