Memory leaks CUDA内核代码的设备内存:是否可显式管理?

Memory leaks CUDA内核代码的设备内存:是否可显式管理?,memory-leaks,cuda,Memory Leaks,Cuda,背景: GeForce GTX 480上的CUDA 4.0、Linux 64位、NVIDIA UNIX x86_64内核模块270.41.19 我试图在我的程序中找到(设备)内存泄漏。我使用运行时API和cudaGetMemInfo(免费、总计)来测量设备内存使用情况。在内核执行之后,我注意到一个显著的损失(在本例中为31M)。内核代码本身不分配任何设备内存。所以我猜它是留在设备内存中的内核代码。即使是我也会认为内核没有那么大。(有没有办法确定内核的大小?) 内核代码何时加载到设备内存中?我猜在

背景: GeForce GTX 480上的CUDA 4.0、Linux 64位、NVIDIA UNIX x86_64内核模块270.41.19

我试图在我的程序中找到(设备)内存泄漏。我使用运行时API和cudaGetMemInfo(免费、总计)来测量设备内存使用情况。在内核执行之后,我注意到一个显著的损失(在本例中为31M)。内核代码本身不分配任何设备内存。所以我猜它是留在设备内存中的内核代码。即使是我也会认为内核没有那么大。(有没有办法确定内核的大小?)

内核代码何时加载到设备内存中?我猜在执行主机代码行时:

kernel<<<geom>>>(params);
内核(params);
对吧?? 调用后,代码是否仍保留在设备内存中?如果是这样,我可以显式卸载代码吗


我关心的是设备内存碎片。设想一个大的交替设备内存分配和内核执行序列(不同的内核)。然后过了一段时间,设备内存变得非常稀缺。即使您释放了一些内存,内核代码仍然只剩下内核之间的空间供新的分配使用。这将在一段时间后导致巨大的内存碎片。这就是CUDA的设计方式吗?

您观察到的内存分配由CUDA上下文使用。它不仅保存内核代码,还保存任何其他静态范围设备符号、纹理、用于本地内存、printf和heap的每线程暂存空间、常量内存以及驱动程序和CUDA运行时本身所需的gpu内存。当二进制模块加载或PTX代码由驱动程序JIT编译时,这些内存中的大部分只分配一次。最好将其视为固定的开销,而不是泄漏。PTX代码中有200万条指令限制,当前的硬件使用32位字作为指令,因此,与所需的其他全局内存开销相比,即使是允许的最大内核代码的内存占用也很小


在CUDA的最新版本中,有一个运行时API调用,它允许对给定上下文可以消耗的暂存空间量进行某种控制。请注意,可以将限制设置为低于设备代码要求的值,在这种情况下,可能会导致运行时执行失败。

是否使用任何全局内存?全局内存将一直保持分配状态,直到您关闭设备或cuda释放它(如果它是cudamalloc'ed)内核被定义为“全局”,但其他任何东西都不是。这里的“全局”并不意味着
\uuuu Global\uuuuu
关键字,它只是指在.cu文件的全局范围内声明的任何内容或通过cudamalloc分配的任何内存。因此,例如,如果您在.cu文件的全局范围内有
int8[1024]
,或者如果您曾经调用
cudamaloc(8*1024)
而没有匹配的cudaFree,您将有一个出色的1KB内存占用。感谢您的回答!您知道在上下文重置之前内核代码是否仍保留在该内存空间中吗?或者它就像内核代码的缓存?如果一个程序有大量不同的内核,它们是否都留在内存中呢。当模块加载到上下文中时,将加载所有外部可见的符号和与体系结构兼容的二进制有效载荷。但我不知道它们是否在加载时直接进入设备。