我正在分析我的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所维持的所谓临时空间有关。内核代码的一种内存池,可以动态增长和缩小。但那是猜测。它也被分配在设备存储器中。
任何见解?
答案 0 :(得分:14)
与暂存空间无关,它是寻址系统的结果,允许在主机和多个GPU之间进行统一的压缩和对等访问。 CUDA驱动程序使用内核的虚拟内存系统在单个虚拟地址空间中注册所有GPU内存+主机内存。它实际上并不是内存消耗本身,它只是将所有可用地址空间映射到线性虚拟空间以进行统一寻址的“技巧”。