CUDA内存是如何管理的?
当我运行只分配少量全局内存(低于20m)的CUDA程序时,出现了“内存不足”错误。(从其他人的帖子中,我认为问题与内存碎片有关)我试图理解这个问题,并意识到我有几个与CUDA内存管理相关的问题CUDA内存是如何管理的?,cuda,nvidia,gpu,Cuda,Nvidia,Gpu,当我运行只分配少量全局内存(低于20m)的CUDA程序时,出现了“内存不足”错误。(从其他人的帖子中,我认为问题与内存碎片有关)我试图理解这个问题,并意识到我有几个与CUDA内存管理相关的问题 CUDA中是否有虚拟内存概念 如果CUDA终止后,只允许一个内核同时在CUDA上运行,那么它使用或分配的所有内存都会释放吗?如果没有,这些内存何时释放 如果CUDA上允许运行多个内核,如何确保它们使用的内存不重叠 有人能帮我回答这些问题吗?谢谢 编辑1:操作系统:x86_64 GNU/Linux CUDA
cudamaloc
分配的内存从不重叠。对于内核在运行时分配的内存,应该有足够的可用内存。如果内存不足,尝试启动内核(我只是猜测一下),应该会收到“未知错误”错误消息。驱动程序无法启动和/或执行内核运行时代码可用的设备内存基本上计算为
Free memory = total memory
- display driver reservations
- CUDA driver reservations
- CUDA context static allocations (local memory, constant memory, device code)
- CUDA context runtime heap (in kernel allocations, recursive call stack, printf buffer, only on Fermi and newer GPUs)
- CUDA context user allocations (global memory, textures)
如果您收到内存不足消息,则在用户代码尝试获取GPU内存之前,前三项中的一项或多项可能正在消耗大部分GPU内存。如前所述,如果您没有在显示GPU上运行,那么上下文静态分配很可能是问题的根源。CUDA的工作原理是在设备上建立上下文时预先分配上下文所需的所有内存。有很多东西被分配来支持上下文,但是上下文中最大的消费者是本地内存。对于设备上的每个多处理器,运行时必须为每个多处理器可以同时运行的最大线程数保留上下文中任何内核将消耗的最大本地内存量。如果在一个有很多多处理器的设备上加载一个本地内存密集型内核,这可能会占用数百Mb的内存
了解可能发生的情况的最佳方法是编写一个没有设备代码的主机程序,该程序建立上下文并调用
cudaMemGetInfo
。这将显示设备在最小上下文开销的情况下有多少内存。然后运行有问题的代码,在第一个cudamaloc
调用之前添加相同的cudaMemGetInfo
调用,该调用将为您提供上下文正在使用的内存量。这可能会让你了解内存的去向。如果您在第一次调用cudamaloc
时出现故障,则碎片问题不太可能出现。您是否可以编辑该问题,以包括您使用的操作系统、GPU和cuda版本,以及GPU是显示设备还是非显示设备。这将关系到您问题的正确答案。为了回答额外的问题-用户可观察到的碎片发生在上下文中,没有办法更改GPU内的内存映射,这一切都由主机驱动程序处理。正如您所解释的,上下文分配由上下文静态分配组成,上下文用户分配和CUDA上下文运行时堆。我认为上下文静态分配和上下文用户分配的大小是预先决定的。因此,我认为内存碎片的唯一原因是上下文运行时堆,它仅在费米体系结构上。对吗?我猜系统将为上下文运行时堆预先分配一块内存,以便启用内核内的动态内存分配。你能把它编辑成只有最初的回溯,然后是一堆问题吗?谢谢你的回复