cudaMemGetInfo不是常量



我正在测试动态分配,即

__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));

事实确实如此。

  1. 注意:当尝试不调用函数AND时cudaMemGetInfo在循环中,它从800减少到650莫,我得出结论,控制台的输出大约需要150莫。事实上,当尝试上面写的代码时,结果并不是改变但它是巨大的
  2. 循环后,我的可用内存减少了约50Mo(希望通过注释对内核的调用,我不会减少任何内存)。当我在内核中添加delete(temp)时,它似乎并没有减少多少浪费的内存,我仍然减少了大约30Mo。为什么
  3. 在循环之后使用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内存的上下文初始化序列。

最新更新