我在集成分支上使用cuda设备,在完成工作时仍然有一些段错误。
每次崩溃后,我的内存消耗增加了500 Mo(使用free -m
,htop
和另外一个,但我不记得名字)。这个内存永远不会在这台带有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
但它说我的计算机不支持它。
问题是:
版:
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
答案 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运行时或驱动程序在应用程序退出时缺少主机资源释放很可能不是根本原因。
我建议你修改我的代码以适应你机器上物理内存的大小(使用物理内存的一半)并按照我在循环中的方式运行它,直接在之前或之后进行内存报告。我非常怀疑你会看到与我在这个答案中发布的内容有什么不同。如果您这样做,我强烈建议您更新最新版本的驱动程序。