2015-12-30 27 views
1

我在集成分支上使用cuda设备,在完成工作时仍然存在段故障。如何避免与Cuda发生segfault内存泄漏

每次崩溃后,我的内存消耗增加了500Mo(使用free -m,htop和另一个,但我不记得名字)。这个内存不会在这台带有4Go内存的计算机上被释放,所以我必须在一些崩溃之后重新启动,否则内存交换和它真的非常慢(通常当内存交​​换发生时)。

我知道很好的答案是:“修复你的段错误!”但我想了解为什么会发生这种情况,我该如何预防这种情况。

我读过CUDA内存应该由segfault上的操作系统发布,它看起来好像没有。当我尝试调试我的程序时,我注意到如果我修复了段错误,内存是正确释放的,但是如果我也对cuda发行版发表评论:cudaFreeHost(buf)(seg段已修复),我仍然有内存泄漏。

我的记忆被分配为固定页面:cudaHostAlloc(&ret, n*sizeof(my_struct), cudaHostAllocPortable)

我想确保使用unique_ptr调用“免费”代码,但它不会解决segfault的问题。

我看着CUDA的持久模式:http://docs.nvidia.com/deploy/driver-persistence/index.html,但它在我的计算机上禁用(我使用nvidia-smi进行了检查)。

我试图重置cuda设备:nvidia-smi -r但它表示它不支持我的电脑。

问题是:

  • 我们怎么能要求的程序(或OS)在程序结束时释放这些资源?
  • 如果我们不能,命令是否存在以在崩溃后恢复这些资源?

  • CUDA 6.0.1

  • GCC 4.9.2

  • 驱动程序版本:340.65

  • 卡:610M的GeForce

更新

这里是一个示例代码来重现该问题。有评论的话,我每次跑10MO。

#include <cuda.h> 
#include <cuda_runtime.h> 

int main() { 

    int *ret; 
    cudaHostAlloc(&ret, 10000000 * sizeof(*ret), cudaHostAllocPortable); 
    //cudaFreeHost(ret); 
    return 0; 
} 

更新2

   total  used  free  shared buffers  cached 
Mem:  3830056 1487156 2342900  66336  142840  527088 
-/+ buffers/cache:  817228 3012828 
Swap:  7811068   0 7811068 
1Erreur de segmentation 
2Erreur de segmentation 
3Erreur de segmentation 
4Erreur de segmentation 
5Erreur de segmentation 
6Erreur de segmentation 
7Erreur de segmentation 
8Erreur de segmentation 
9Erreur de segmentation 
10Erreur de segmentation 
11Erreur de segmentation 
12Erreur de segmentation 
13Erreur de segmentation 
14Erreur de segmentation 
15Erreur de segmentation 
16Erreur de segmentation 
17Erreur de segmentation 
18Erreur de segmentation 
19Erreur de segmentation 
20Erreur de segmentation 
      total  used  free  shared buffers  cached 
Mem:  3830056 1766580 2063476  64152  142860  531032 
-/+ buffers/cache: 1092688 2737368 
Swap:  7811068   0 7811068 
+1

你能发布其示出了明显的内存泄漏短REPRO情况?我不确定你对这里发生的事情的诊断是正确的,也可能是你误解了发生的事情。此外,你正在运行一个两岁的CUDA工具包和一个一岁的驱动程序。你有没有考虑过升级以查看行为是否相同? – talonmies

+0

我添加了一个示例代码repro case。我同意,CUDA版本应该是最新的,但我没有时间做这个迁移。我可能/会试图去做,看看它是否会再次发生。 –

+1

我有一个64位系统上与352.39驱动程序和CUDA 6运行RAM和16GB运行代码,在shell循环1000次,并没有发现内存泄露的。我不知道你的代码或你的系统正在发生什么,但是CUDA不会按照你所建议的方式泄漏主机内存。 – talonmies

回答

2

我已经构建了摄制情况略加修改:

#include <cuda.h> 
#include <cuda_runtime.h> 
#include <signal.h> 

int main() { 

    int *ret; 
    const size_t sz = 1 << 30; 
    cudaHostAlloc(&ret, sz * sizeof(*ret), cudaHostAllocPortable); 
    raise(SIGSEGV); 
    return 0; 
} 

这在我的系统应该分配固定便携式内存8GB和引发段错误,产生异常退出和核心转储。我与352.39驱动程序和CUDA 6运行在shell循环,根据您的分析,这应该引起两个或三个运行中的泄漏和缓存反覆跑这一个16GB的机器上:

$ free; for i in {1..20}; do echo -n $i; ./a.out; done; free 
      total  used  free  shared buffers  cached 
Mem:  16308996 3509924 12799072   0  303588 2313332 
-/+ buffers/cache:  893004 15415992 
Swap:  8257532   0 8257532 
1Segmentation fault (core dumped) 
2Segmentation fault (core dumped) 
3Segmentation fault (core dumped) 
4Segmentation fault (core dumped) 
5Segmentation fault (core dumped) 
6Segmentation fault (core dumped) 
7Segmentation fault (core dumped) 
8Segmentation fault (core dumped) 
9Segmentation fault (core dumped) 
10Segmentation fault (core dumped) 
11Segmentation fault (core dumped) 
12Segmentation fault (core dumped) 
13Segmentation fault (core dumped) 
14Segmentation fault (core dumped) 
15Segmentation fault (core dumped) 
16Segmentation fault (core dumped) 
17Segmentation fault (core dumped) 
18Segmentation fault (core dumped) 
19Segmentation fault (core dumped) 
20Segmentation fault (core dumped) 
      total  used  free  shared buffers  cached 
Mem:  16308996 3510740 12798256   0  303588 2313272 
-/+ buffers/cache:  893880 15415116 
Swap:  8257532   0 8257532 

但是,你可以看到,在分配160Gb的固定内存之后只会产生0.006%的空闲内存,并且永远不会调用内存释放API或允许代码按照正常代码路径退出。没有内存泄漏或空闲资源发生净变化。

CUDA驱动程序和运行时会在出口处释放主机和GPU资源,无论是正常还是不正常的,有或没有显式调用以释放内存的API。我无法告诉你代码或系统有什么问题,但CUDA运行时或驱动程序退出应用程序时缺少主机资源释放很可能不是根本原因。

我会鼓励你修改我的代码,以适应物理内存的大小,你的机器上(使用一半的物理内存),然后运行它,因为我在一个循环中已经做了内存之前或之后,直接汇报工作。我非常怀疑你会看到与我在这个答案中发布的内容不同的东西。如果这样做,我会强烈建议将驱动程序更新为最新的发行版驱动程序。

+0

我复制/粘贴您的代码以运行完全相同的测试。我的结果是: 首先免费:使用= 1205504 第二次自由:使用= 1519068 我使用相同的值比你。我同意它不会完全泄漏,但它是8%,不容忽视。我知道cuda运行时或驱动程序或任何应该释放资源,但显然不完全在我的情况。 –

+0

@ P.Brunet:你可以在某处发布完整的免费输出吗? (也许在你的问题中编辑)。这听起来像你只是误解了free/top的输出实际上意味着什么。当您将一半物理内存分配到单个连续缓冲区时,总可用内存变化为8%并不意味着您有内存泄漏。 Linux内核动态保留并释放文件系统缓存和缓冲区,这可以很容易地解释这种大小的差异。 – talonmies

+0

我明白你不想相信我,所以我把完整的结果,但我想我可以读它。如果它真的是缓存或缓存机制,那么当OS需要时将其删除,它将不会在稍后进行交换。在这种情况下(我现在重新运行),它也是300M内存泄漏。 –