如何使用Cuda

时间:2015-12-30 08:32:18

标签: c++ c memory memory-leaks cuda

我在集成分支上使用cuda设备,在完成工作时仍然有一些段错误。

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

我知道答案很好:“修复你的段错!”但我想了解为什么会发生这种情况,我该怎样才能阻止它。

我读到CUDA内存应该由操作系统在segfault上发布,看起来没有。

当我尝试调试我的程序时,我注意到如果我修复了段错误,内存是正确的,但如果我也评论cuda释放行:cudaFreeHost(buf)(修复了段错误),我仍然有内存泄漏。

我的记忆被分配为固定页面: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

  • 卡片:GeForce 610M

更新

以下是重现问题的示例代码。使用注释行,我每次运行泄漏10 Mo.

#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 个答案:

答案 0 :(得分:2)

我构建了一个稍微修改过的repro案例版本:

#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运行时的16Gb机器上运行这个shell循环,根据你的分析,这会导致泄漏和缓存在两到三次运行中抖动:

$ 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的固定内存并且从不调用内存释放API或允许代码遵循正常的代码路径退出时,只会使可用内存减少0.006%。没有内存泄漏或免费资源发生净变化。

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

我建议你修改我的代码以适应你机器上物理内存的大小(使用物理内存的一半)并按照我在循环中的方式运行它,直接在之前或之后进行内存报告。我非常怀疑你会看到与我在这个答案中发布的内容有什么不同。如果您这样做,我强烈建议您更新最新版本的驱动程序。