我正在测试动态分配,即
__device__ double *temp;
__global__
void test(){
temp = new double[125000]; //1MB
}
调用此函数100次以查看内存是否在减少:
size_t free, total;
CUDA_CHECK(cudaMemGetInfo(&free, &total));
fprintf(stdout,"t### Available VRAM : %g Mo/ %g Mo(total)nn", free/pow(10., 6), total/pow(10., 6));
for(int t=0;t<100;t++){
test<<<1, 1>>>();
CUDA_CHECK(cudaDeviceSynchronize());
fprintf(stdout,"t### Available VRAM : %g Mo/ %g Mo(total)nn", free/pow(10., 6), total/pow(10., 6));
}
CUDA_CHECK(cudaMemGetInfo(&free, &total));
fprintf(stdout,"t### Available VRAM : %g Mo/ %g Mo(total)nn", free/pow(10., 6), total/pow(10., 6));
事实确实如此。
- 注意:当尝试不调用函数AND时cudaMemGetInfo在循环中,它从800减少到650莫,我得出结论,控制台的输出大约需要150莫。事实上,当尝试上面写的代码时,结果并不是改变但它是巨大的
- 循环后,我的可用内存减少了约50Mo(希望通过注释对内核的调用,我不会减少任何内存)。当我在内核中添加delete(temp)时,它似乎并没有减少多少浪费的内存,我仍然减少了大约30Mo。为什么
- 在循环之后使用cudaFree(temp)或cudaViceReset()也没有多大帮助。为什么?如何释放内存
听起来你真的需要先阅读这对问答,然后再进一步。
在内核内用CCD_ 1分配的内存来自静态运行时堆;懒惰;程序运行时由CUDA运行库启动的上下文建立。建立上下文的第一个CUDA调用还将加载包含内核代码的模块,并为随后的内核调用保留本地内存、运行时缓冲区和运行时堆。这就是你观察到的大部分内存消耗的来源。运行时API包含一个允许用户控制分配大小的调用。
你应该会发现在CUDA版本4或5上做这样的事情:
size_t free, total;
CUDA_CHECK(cudaMemGetInfo(&free, &total));
fprintf(stdout,"t### Available VRAM : %g Mo/ %g Mo(total)nn",
free/1e6, total/1e6);
cudaFree(0);
CUDA_CHECK(cudaMemGetInfo(&free, &total));
fprintf(stdout,"t### Available VRAM : %g Mo/ %g Mo(total)nn",
free/1e6, total/1e6);
// Kernel loop follows
【免责声明:在浏览器中编写,使用风险自负】
应该显示cudaFree(0)
调用后可用内存下降,因为这应该启动占用GPU内存的上下文初始化序列。