CUDA运行时在初始化时为什么要保留80 GiB虚拟内存?

12

我对我的Cuda 4程序进行了分析,结果发现在某个阶段,该运行进程使用了超过80 GiB的虚拟内存。这比我预期的要多得多。 经过对内存映射演变的检查以及比较执行代码的行号后,发现在这些简单指令之后,虚拟内存使用量增加到了80 GiB以上:

  int deviceCount;
  cudaGetDeviceCount(&deviceCount);
  if (deviceCount == 0) {
    perror("No devices supporting CUDA");
  }

显然,这是第一个Cuda调用,因此运行时已经初始化。在此之后,内存映射如下(截断):

Address           Kbytes     RSS   Dirty Mode   Mapping
0000000000400000   89796   14716       0 r-x--  prg
0000000005db1000      12      12       8 rw---  prg
0000000005db4000      80      76      76 rw---    [ anon ]
0000000007343000   39192   37492   37492 rw---    [ anon ]
0000000200000000    4608       0       0 -----    [ anon ]
0000000200480000    1536    1536    1536 rw---    [ anon ]
0000000200600000 83879936       0       0 -----    [ anon ]

现在,这个巨大的内存区域映射到虚拟内存空间中了。

好吧,或许这不是一个大问题,因为在Linux中保留/分配内存并不会有什么作用,除非您真正写入了该内存。但这真的很烦人,例如MPI作业必须指定作业可使用的最大vmem量。而80GiB只是Cuda作业的下限 - 还必须添加所有其他东西。

我可以想象这与Cuda维护的所谓的临时空间有关。一种可动态增长和收缩的内核代码的内存池。但这只是猜测。此外,它分配在设备内存中。

有什么见解吗?

1个回答

14

与临时空间无关,这是地址系统的结果,该系统允许主机和多个GPU之间进行统一寻址和点对点访问。CUDA驱动程序使用内核的虚拟内存系统将所有GPU(s)内存+主机内存注册在单个虚拟地址空间中。它实际上不是内存消耗本身,而只是一种“技巧”,用于将所有可用地址空间映射到线性虚拟空间以进行统一寻址。


好的,明白了。那么在我的情况下,主机安装了48GB RAM + 8GB交换空间和4个6GB的GPU,总共是80GB。太棒了!这是否意味着如果我在普通堆上分配内存,它也会出现在这80GB中? - ritter
7
@Frank:我能用一下你的电脑吗? :) - Roger Dahl
如果Frank的电脑有48GB的RAM,而CUDA为其“技巧”要求80GB的内存,你是说交换文件会膨胀到32GB吗?这80GB具体分配在哪里? - mchen
1
@MiloChen:没有特定位置。该进程只是将所有GPU内存和系统内存映射到一个虚拟地址空间中,进程可以统一地寻址该地址空间。 - talonmies
如何禁用它?在我的应用程序中,CUDA需要50GB的页面文件。 - iperov
显示剩余2条评论

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