2013-07-29 15 views
0

我測試的動態分配,即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)\n\n", 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)\n\n", free/pow(10., 6), total/pow(10., 6)); 
    } 
CUDA_CHECK(cudaMemGetInfo(&free, &total)); 
fprintf(stdout,"\t### Available VRAM : %g Mo/ %g Mo(total)\n\n", free/pow(10., 6), total/pow(10., 6)); 

,它實際上是。

  1. 注:當試圖而不調用函數和 cudaMemGetInfo內循環,這是減少從800到650 莫,我得出的結論是到控制檯輸出了〜150密蘇里州 事實上,當嘗試像上面寫的代碼,結果不會 更改。但它是巨大的!
  2. 循環後我得到約50Mo的可用內存減少(我沒有通過給內核發出有用的評論來減少)。當我在內核中添加一個刪除(temp)時,似乎不會減少浪費的內存量,我仍然會減少~30Mo。爲什麼?
  3. 循環後使用cudaFree(temp)或cudadeviceReset()也沒有多大幫助。爲什麼?以及如何釋放內存?

回答

3

這真的聽起來像你需要閱讀這questionanswer對,然後再進一步。

您在內核中分配的內存來自內核中的靜態運行時堆,該靜態運行時堆作爲CUDA運行時在程序運行時啓動的「延遲」上下文建立的一部分進行分配。建立上下文的第一個CUDA調用還將加載包含內核代碼的模塊,併爲隨後的內核調用保留本地內存,運行時緩衝區和運行時堆。這就是你觀察到的大部分內存消耗來自哪裏。運行時API包含一個允許用戶控制分配大小的call

你會發現,做這樣的事情上CUDA版本4或5:

size_t free, total; 
CUDA_CHECK(cudaMemGetInfo(&free, &total)); 
fprintf(stdout,"\t### Available VRAM : %g Mo/ %g Mo(total)\n\n", 
        free/1e6, total/1e6); 

cudaFree(0); 

CUDA_CHECK(cudaMemGetInfo(&free, &total)); 
fprintf(stdout,"\t### Available VRAM : %g Mo/ %g Mo(total)\n\n", 
        free/1e6, total/1e6); 

// Kernel loop follows 

[免責聲明:寫在瀏覽器中,使用風險自擔]

應顯示後的可用內存下降調用cudaFree(0),因爲這會啓動上下文初始化序列,這會消耗GPU上的內存。

+0

好的,謝謝!我對cuda環境的概念仍然有困難,但我正在閱讀文檔。 –

+0

@FrançoisLaenen:上下文是給定GPU上的主機進程/線程特定的「會話」。每個上下文在GPU上都有自己的虛擬地址空間,CUDA運行時支持,代碼和數據將加載到該空間中。在運行時API中,這大部分是隱藏的,但如果您查看驅動程序API文檔,則可以看到顯式調用管理上下文。 – talonmies

+0

好吧,我現在好了。舉例來說,cudaMalloc從主機返回的指針將不會被另一個上下文使用,因爲它將被加載到第一個上下文的VAS中? –