【问题标题】:Why does the Cuda runtime reserve 80 GiB virtual memory upon initialization?为什么 Cuda 运行时在初始化时会保留 80 GiB 虚拟内存?
【发布时间】:2021-06-25 11:24:06
【问题描述】:

我正在分析我的 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 维护的所谓暂存空间有关。一种可以动态增长和收缩的内核代码内存池。但那是猜测。它也分配在设备内存中。

有什么见解吗?

【问题讨论】:

    标签: cuda


    【解决方案1】:

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

    【讨论】:

    • 好的,有道理。因此,在我的情况下,主机安装了 48 GB RAM + 8 GB 交换空间和 4 个 6 GB 的 GPU,总共 80 GB。答对了!这是否意味着如果我在普通堆上分配,这也会出现在这些 80GB 内?
    • 堆只是每个上下文的每个 GPU 内存的分配。由于堆,您不会看到虚拟内存发生变化,但 API 报告给定 GPU 上的可用内存会减少。
    • @Frank:我可以要你的电脑吗? :)
    • 因此,如果 Frank 的计算机有 48GB 的​​ RAM 并且 CUDA 需要 80GB 的内存来实现它的“技巧”,你是说交换文件会膨胀到 32GB 吗?这 80GB 究竟分配在哪里?
    • @MiloChen:无处可去。该进程只是将所有 GPU(s) 内存和所有系统内存映射到该进程可以统一寻址的单个 虚拟 地址空间。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-09-27
    • 2022-08-16
    • 2021-01-28
    • 2015-01-24
    • 1970-01-01
    • 2012-11-27
    相关资源
    最近更新 更多