问题 为什么Cuda运行时在初始化时保留80 GiB虚拟内存?


我正在分析我的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数量来指定。而对于Cuda工作而言,80GiB只是一个较低的边界 - 人们也必须添加所有其他东西。

我可以想象它与Cuda所维持的所谓划痕空间有关。内核代码的一种内存池,可以动态增长和缩小。但这是猜测。它也分配在设备内存中。

任何见解?


12932
2017-07-24 12:47


起源



答案:


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


13
2017-07-24 13:27



好的,有道理。因此,在我的情况下,主机安装了48 GB RAM + 8 GB交换,4个GPU,每个6 GB,总共80 GB。答对了!这是否意味着如果我在普通堆上分配,这也会出现在这些80GB内? - ritter
堆只是每个上下文的每个GPU内存的分配。由于堆,您不会看到虚拟内存的更改,但是在给定GPU上API报告的可用内存将减少。 - talonmies
@Frank:我可以买你的电脑吗? :) - Roger Dahl
因此,如果Frank的计算机有48GB的RAM而CUDA需要80GB的内存用于其“技巧”,你是否说交换文件会膨胀到32GB? 80GB的确切分配在哪里? - mchen
@MiloChen:无处可去。该过程简单地将所有GPU(s)内存和所有系统内存映射为单个内存 虚拟 地址空间,进程可以统一解决。 - talonmies


答案:


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


13
2017-07-24 13:27



好的,有道理。因此,在我的情况下,主机安装了48 GB RAM + 8 GB交换,4个GPU,每个6 GB,总共80 GB。答对了!这是否意味着如果我在普通堆上分配,这也会出现在这些80GB内? - ritter
堆只是每个上下文的每个GPU内存的分配。由于堆,您不会看到虚拟内存的更改,但是在给定GPU上API报告的可用内存将减少。 - talonmies
@Frank:我可以买你的电脑吗? :) - Roger Dahl
因此,如果Frank的计算机有48GB的RAM而CUDA需要80GB的内存用于其“技巧”,你是否说交换文件会膨胀到32GB? 80GB的确切分配在哪里? - mchen
@MiloChen:无处可去。该过程简单地将所有GPU(s)内存和所有系统内存映射为单个内存 虚拟 地址空间,进程可以统一解决。 - talonmies