2015-03-03 68 views
1

我不能製作新的標籤,但它應該在MANAGEDCUDA標籤上,因爲我使用該框架在C#中使用CUDA。在CUDA設備中的內存分配不是預期的

我分配2個INT陣列,該代碼進行測試:

Console.WriteLine("Cells: "+sum+" Expected Total Memory (x4): "+sum*4); 
int temp= 0; 
temp = cntxt.GetFreeDeviceMemorySize(); 
Console.Write("\n Memory available before:" + cntxt.GetFreeDeviceMemorySize() + "\n"); 
CudaDeviceVariable<int> matrix = new CudaDeviceVariable<int>(sum); 
CudaDeviceVariable<int> matrixDir = new CudaDeviceVariable<int>(sum); 
Console.Write("\n Memory available after allocation:" + cntxt.GetFreeDeviceMemorySize() + "\n"); 
Console.WriteLine("Memory took: "+(temp - cntxt.GetFreeDeviceMemorySize())); 
Console.WriteLine("Diference between the expected and allocated: " + ((temp - cntxt.GetFreeDeviceMemorySize())-sum*8)); 

運行後我在控制檯得到這個:

Console Run

+1

習慣問一個問題。我想你想知道爲什麼分配了大約3MB的數據後,出現了大約40KB的差異?存在與分配相關的粒度/開銷,而且該設備具有類似於運行在其上的操作系統的東西,這需要設備存儲器用於它自己的內務處理任務。 – 2015-03-03 01:13:20

+1

回答[tag:cuda]問題的用戶池已經相對有限,進一步拆分標籤只會使您的問題不太明顯。 – 2015-03-03 01:21:45

回答

6

當你通過分配器(malloc分配內存, cudaMalloc,...),它需要跟蹤您分配的特殊元數據結構中的字節。例如,此元數據可能包含分配的字節數和它們在內存中的位置,一些用於調整分配的填充以及緩衝區溢出檢查。

爲了減少管理開銷,大多數現代分配器使用頁面,也就是說,它們以固定大小的不可分割塊分配內存。在許多主機系統上,這個大小默認爲4 kB。

在您的具體情況中,看起來CUDA將以64 kB的頁面爲您的內存分配請求提供服務。也就是說,如果你要求56 kB,CUDA無論如何都會爲你提供64 kB,而未使用的8 kB卻是「浪費」的(從你的應用程序的角度來看)。

當您請求1552516字節(即23.7頁)的分配時,運行時會改爲爲您提供24頁(1572864字節):這是額外的20348字節。加倍(因爲你有2個數組),這就是你的40696字節差異來自哪裏。

注:頁面大小因GPU和驅動程序版本而異。您可以試着自己找到它,或者搜索其他人發佈的結果。無論如何,這是(據我所知)沒有記錄,因此,如果您打算將您的程序移植到便攜式計算機上,則可能不會被依賴。