2011-08-22 80 views
0

語境: CUDA 4.0,Linux的64位,NVIDIA UNIX x86_64的內核模塊270.41.19,在的GeForce GTX 480CUDA內核代碼的設備內存:是否明確可管理?

我試圖找到我的程序(設備)內存泄漏。我使用運行時API和cudaGetMemInfo(free,total)來測量設備內存使用情況。內核執行後我注意到了一個重大的損失(在這種情況下是31M)。內核代碼本身不分配任何設備內存。所以我猜想它是保留在設備內存中的內核代碼。即使我會認爲內核不是那麼大。 (有沒有確定內核大小的方法?)

何時將內核代碼加載到設備內存中?我想執行主機代碼行:

kernel<<<geom>>>(params); 

對不對? 在調用之後代碼是否保留在設備內存中?如果是這樣,我可以明確卸載代碼嗎?

我擔心的是設備內存碎片。考慮交替設備內存分配和內核執行的大量序列(不同的內核)。過了一段時間後,設備內存變得非常稀少。即使你釋放了一些內存,內核代碼仍然只留下內核之間的空間用於新分配。這會在一段時間後導致巨大的內存碎片。這是CUDA的設計方式嗎?

+0

你在使用任何全局內存嗎?全局內存將保持分配狀態,直到您關閉設備或釋放它爲止(如果它是cudamalloc'ed) – asm

+0

內核被定義爲「__global__」,但沒有別的。 – ritter

+0

這裏的全局並不意味着'__global__'關鍵字,它只是意味着在你的.cu文件或通過cudamalloc分配的任何內存中在全局範圍內聲明的任何內容。因此,例如,如果在.cu文件的全局範圍內有'int8 [1024]',或者如果您在沒有匹配的cudaFree的情況下調用'cudaMalloc(8 * 1024)',您將擁有突出的1KB內存佔用空間。 – asm

回答

2

您正在觀察的內存分配由CUDA上下文使用。它不僅包含內核代碼,還包含本地存儲器的任何其他靜態作用域設備符號,紋理,每線程暫存空間,printf和堆,常量內存以及驅動程序和CUDA運行時本身所需的gpu內存。大多數內存只能分配一次,當加載一個二進制模塊時,或者驅動程序編譯的PTX代碼是JIT。最好把它看作是一個固定的開銷,而不是泄漏。 PTX代碼中有200萬條指令限制,當前硬件使用32位字指令,所以即使是最大允許內核代碼的內存佔用量與其所需的其他全局內存開銷相比也較小。

在最新版本的CUDA中,有一個運行時API調用cudaDeviceSetLimit,它允許對給定上下文消耗的暫存空間量進行一些控制。請注意,可以將限制設置爲低於設備代碼要求的值,在這種情況下,可能會導致運行時執行失敗。

+0

感謝您的回答!你知道內核代碼是否保留在內存空間中,直到上下文重置?還是它像內核代碼的緩存?如果一個程序擁有大量不同的內核,它們是否都留在內存中呢? – ritter

+0

沒有記錄。將模塊加載到上下文中時,將加載所有外部可見符號和體系結構兼容二進制有效內容。但是,他們是否在加載時直接進入設備是我不知道的。 – talonmies