CUDA脚本执行后,GPU内存没有自动释放

3
我在使用CUDA脚本后遇到了显卡保留内存的问题(即使使用了cudaFree()函数)。开机时总已用内存约为128MB,但脚本执行后会在中途用完内存。请注意,有一部分内容需要翻译成专有名词“nvidia-smi”。
  +------------------------------------------------------+                       
| NVIDIA-SMI 340.29     Driver Version: 340.29         |                       
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  GeForce GTX 660 Ti  Off  | 0000:01:00.0     N/A |                  N/A |
| 10%   43C    P0    N/A /  N/A |   2031MiB /  2047MiB |     N/A      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Compute processes:                                               GPU Memory |
|  GPU       PID  Process name                                     Usage      |
|=============================================================================|
|    0            Not Supported                                               |
+-----------------------------------------------------------------------------+

有没有办法在不重启的情况下释放这些内存,也许可以通过终端命令实现?

如果我在CUDA脚本中没有正确管理内存,这种行为是否正常,或者当脚本停止/退出时,这些内存是否应该自动释放?


2
如果您的程序实际上已经退出,CUDA上下文将被销毁,并释放它所使用的任何资源。您确定您的程序没有一堆僵尸或挂起的实例仍在后台运行吗? - talonmies
那就是问题所在,我原以为进程会在崩溃/完成时自动终止。我检查了系统监视器,发现我运行的输出文件有几个进程。杀掉这些进程后,GPU内存就释放了。是否有一个命令可以在意外停止(例如ctrl+z退出),而不仅仅是在cudaMalloc失败时释放所有GPU内存?如果你把这个作为答案,我也会标记为正确的,再次感谢 - Jamie Stuart Robin Parsons
1
你明白Ctrl-Z并不会向前台进程发送SIGINT或SIGTERM信号,它发送的是SIGTSTP(与Ctrl-C或kill不同)。除非在应用程序中注册一个信号处理程序来捕获SIGSTP并导致应用程序退出,否则它将永远不会知道Ctrl-Z是否被按下(这是有意设计的)。这听起来像是用户行为问题,而不是编程问题。 - talonmies
好的,谢谢你的信息。 - Jamie Stuart Robin Parsons
1个回答

6
CUDA运行时API会自动注册一个拆除函数,该函数将销毁CUDA上下文并释放应用程序正在使用的任何GPU资源。只要应用程序隐式或显式调用了exit(),则无需进一步用户操作即可释放GPU内存等资源。
如果您发现在运行CUDA代码时似乎没有释放内存,则通常嫌疑人是挂起或后台实例或其他从未调用exit()和未销毁其上下文的代码。这就是本例的原因。
NVIDIA提供了一个API函数cudaDeviceReset,它将在调用时启动上下文销毁。在设计良好的CUDA代码中通常不需要使用此函数,而应尝试确保程序中有一个干净的exit()或从main()返回路径。这将确保运行时库调用上下文销毁处理程序并释放资源。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接