2015-10-20 70 views
1

我們如何使用AleaGpu釋放陣列的GPU內存? (在GPU卡上)我們如何使用AleaGpu釋放陣列的GPU內存? (在GPU卡上)

在函數/子裏面,如果我們想釋放數組dOutputs,dInputs的GPU內存,我們該怎麼做呢?

1 /志 「dOutputs 處置(); dInputs 處置();」。釋放GPU內存?

2 /是否存在用於GPU的「GC.Collect()」?有必要嗎 ?

3 /隨着AleaGpu,我們有一個命令來釋放GPUmemory?

private void button3_Click(object sender, EventArgs e) 
    { 
     textBox3.Text = ""; 
     var worker = Worker.Default; 
     const int rows = 10; 
     const int cols = 5; 
     var rng = new Random(); 
     var inputs = new double[rows, cols]; 
     for (var row = 0; row < rows; ++row) 
     { 
      for (var col = 0; col < cols; ++col) 
      { 
       inputs[row, col] = rng.Next(1, 100); 
      } 
     } 
     var dInputs = worker.Malloc(inputs); 
     var dOutputs = worker.Malloc<double>(rows, cols); 
     var lp = new LaunchParam(1, 1); 
     worker.Launch(Kernel, lp, dOutputs.Ptr, dInputs.Ptr, rows, cols); 
     var outputs = new double[rows, cols]; 
     dOutputs.Gather(outputs); 
     Assert.AreEqual(inputs, outputs); 
     dOutputs.Dispose(); 
     dInputs.Dispose();" 
    } 

3 /由於GPU卡的內存有限,我們需要使用Single/Int16/Int32而不是double。 我想:

 var inputs = new Single[rows, cols]; 
     var dOutputs = worker.Malloc<Single>(rows, cols); 
     var inputs2 = new Int16[rows, cols]; 

 worker.Launch(Kernel, lp, dOutputs.Ptr, dInputs.Ptr, rows, cols); 

不採取它。我得到錯誤「有一些無效的論點」。

我們如何讓worker.Launch(Kernel,lp,...)以Int16,Int32和single?

回答

2

Worker.Malloc()返回的類型是DeviceMemory,這代表了Gpu上的一個內存分配。它是一次性的,所以你可以自己處理它或讓GC清潔它。但是請注意,如果您依賴GC進行收集,則會出現延遲(這是在GC線程中完成的),並且由於Gpu內存都是固定內存(不能交換到磁盤),所以建議您明確地處理它。爲了簡化代碼,您可以使用C#「using」關鍵字。

當然,Alea Gpu適用於這些類型,您遇到的問題是因爲您需要指定確切的類型。請注意,1.0屬於double類型,而1.0f屬於單一類型。原因是,內核函數由委託提供給工作者啓動方法,因此您需要指定正確的數據類型以幫助其找到內核方法。隱式類型轉換在這裏不起作用。對於數字文字,您可以參考here

我做了一個小例子代碼,它的工作原理:

static void Kernel(deviceptr<float> data, float value) 
{ 
    data[0] = value; 
} 

static void Kernel(deviceptr<short> data, short value) 
{ 
    data[0] = value; 
} 

static void Main(string[] args) 
{ 
    var worker = Worker.Default; 
    var lp = new LaunchParam(1, 1); 
    using (var dmemSingle = worker.Malloc<float>(1)) 
    using (var dmemShort = worker.Malloc<short>(1)) 
    { 
     worker.Launch(Kernel, lp, dmemSingle.Ptr, 4.1f); 
     worker.Launch(Kernel, lp, dmemShort.Ptr, (short)1); 
    } 
} 
+0

這很棒! – Emmanuel

0

可以對GPU超載的定義!這是非常好的。 與CPU上的常規代碼類似,您可以爲GPU上的相同功能定義多個定義。

通過使用「using」編碼循環,只要您退出循環,它就會釋放GPU上的內存。優秀 !!!!!

謝謝

+0

是的,重載是好的,但是由於您只是通過名稱「Kernel」給出內核方法,因此您必須給出確切類型的參數,因此我們可以找到您指的是哪個「內核」,這就是爲什麼隱式轉換數字的東西在這裏不起作用。 –

+0

順便說一句,@Emmanuel,如果你接受答案,你能否將答案標記爲「接受答案」? :) –