Matlab 並行編程——CUDA

Matlab 並行編程——CUDA

http://163n.blog.163.com/blog/static/560355522010111083613574/

GPUArray
MATLAB中的GPUArray表示存儲在GPU上的數據。使用gpuArray函數可以將數據從MATLAB工作空間傳送到GPU。例如:
A = data(10);
G = gpuArray(A);

gather

執行以上語句後,G 就是一個MATLAB GPUArray對象了。
當GPU運行完程序後,可以通過gather函數將數據從GPU取回到MATLAB工作空間。
D = gather(G);

其它

GPUArray類也提供了以下靜態方法,可用於直接在GPU上創建數組:
parallel.gpu.GPUArray.ones
parallel.gpu.GPUArray.eye
parallel.gpu.GPUArray.zeros
parallel.gpu.GPUArray.colon
parallel.gpu.GPUArray.Inf
parallel.gpu.GPUArray.true
parallel.gpu.GPUArray.NaN
parallel.gpu.GPUArray.false
以下幾個函數可直接用於獲取GPUArray對象的特性:
classUnderlying, isreal, length, ndims, size

 

實戰:使用MATLAB進行GPU高級編程

http://cuda.it168.com/a2011/0930/1254/000001254551.shtml

在GPU上執行能夠加快我的應用程序嗎?

  GPU能夠對符合以下標準的應用程序進行加速:

  大規模並行—計算能夠被分割成上百個或上千個獨立的工作單元。

  計算密集型—計算消耗的時間顯著超過了花費轉移數據到GPU內存以及從GPU內存轉移出數據的時間。

  不滿足上述標準的應用程序在GPU上運行時可能會比CPU要慢。

  使用MATLAB進行GPU編程

  FFT,IFFT以及線性代數運算超過了100個內置的MATLAB函數,通過提供一個類型爲GPUArray(由並行計算工具箱提供的特殊數組類型)的輸入參數,這些函數就能夠直接在GPU上運行。這些啓用GPU的函數都是重載的,換句話說,這些函數根據傳遞的參數類型的不同而執行不同的操作。

  例如,以下代碼使用FFT算法查找CPU上僞隨機數向量的離散傅里葉變換:

  A = rand(2^16,1);

  B = fft (A);

  爲在GPU上執行相同的操作,我們首先使用gpuArray命令將數據從MATLAB工作空間轉移至GPU設備內存。然後我們能夠運行重載函數fft:

  A = gpuArray(rand(2^16,1));

  B = fft (A);

  fft操作在GPU上而不是在CPU上執行,因爲輸入參數(GPUArray)位於GPU的內存中。

  結果B存儲在GPU當中。然而,B在MATLAB工作空間中依舊可見。通過運行class(B),我們看到B是一個GPUArray。

  class(B)

  ans =

  parallel.gpu.GPUArray

  我們能夠使用啓用GPU的函數繼續對B進行操作。例如,爲可視化操作結果,plot命令自動處理GPUArrays。

  plot(B);

  爲將數據返回至本地的MATLAB工作集,你可以使用gather命令。例如

  C = gather(B);

  C現在是MATLAB中的double,能夠被處理double變量的所有MATLAB函數操作。

  在這個簡單的例子當中,執行單個FFT函數節省的時間通常少於將向量從MATLAB工作集移動到設備內存的時間。一般來說是這樣的但是也取決於硬件和陣列規模。數據傳輸開銷可能變得異常顯著以至於降低了應用的總體性能,尤其是當你重複地在CPU和GPU之間交換數據,執行相對來說很少的計算密集型操作時。更有效率的方式是當數據處於GPU當中時對數據進行一些操作,只在必要的情況下才將數據返回至CPU。

  需要指出的是,和CPU類似,GPU的內存也是有限的。然而,與CPU不同,GPU不能在內存和硬盤之間交換數據。因此,你必須覈實你希望保留在GPU當中的數據不會超出內存的限制,尤其是當用到大規模矩陣時。通過運行gpuDevice命令,可以查詢GPU卡,獲取信息比如名稱,總內存以及可用內存。

  採用MATLAB解波動方程

  爲將上述例子應用到具體的環境中,我們在一個實際的問題中實現GPU的功能。計算目標是解二階波動方程。

  當u=0時到達臨界值。我們使用基於波譜法的算法解空間方程,使用基於二階中心有限差分法的算法解時間方程。

  波譜法通常用於解決偏微分方程。採用波譜法的解決方案接近連續基函數比如正弦和餘弦的線性組合。在這個例子中,我們應用了切比雪夫波譜法,使用切比雪夫多項式作爲基函數。

  我們在每一個時間步長使用切比雪夫波普法計算當前解決方案的在x象限和y象限的二次導數。我們同時使用這些中間數值與舊的解決方案和新的解決方案,應用二階中心有限差分法(也稱爲蛙跳法)計算新的解決方案。我們選擇了保持蛙跳法穩定性的時間步長。

  MATLAB算法是計算密集型的,當網格中元素的數目超過了計算解決方案的增長,算法的執行時間將顯著增加。當在單個CPU上使用2048x2048的網格執行時,完成50個時間步長需要一分多鐘。需要指出的是我們計算的時間已經包括了MATLAB內在的多線程性能優勢。自從R2007a起,MATLAb的一些函數就支持多線程計算。這些函數自動在多線程上執行,並不需要在代碼中顯示指定命令去創建線程。

  當考慮如何使用並行計算工具箱加速計算時,我們將關注每個時間步長所執行的計算指令代碼。圖3距離說明了爲獲取在GPU上運行的算法需要做出的改變。需要指出的是涉及MATLAB操作的計算指令、啓用GPU的重載函數可以從並行計算工具箱獲取。這些操作包括FFT,IFFT,矩陣乘法,以及各種元素明智(element-wise)操作。因此,我們不必改變算法就能夠在GPU執行。只需要在進入每個時間步長計算結果的循環前使用gpuArray將數據轉移到GPU當中。

 

圖 3. 代碼對比工具顯示了CPU版本和GPU版本的差異。

 

CPU和GPU版本共享的代碼超過了84%(在111行當中有94行)。

  計算指令在GPU上執行後,我們將計算結果從GPU轉移至CPU。被啓用GPU的函數所引用的每個變量必須在GPU上創建或者在使用前轉移到GPU上。

  爲將用於光譜分化的一個權重轉變爲GPUArray變量,我們使用

  W1T = gpuArray(W1T);

  某些類型的數組能夠直接在GPU上構造,不用從MATLAB工作集轉移。例如,爲直接在GPU上創建全零矩陣,我們使用

  uxx = parallel.gpu.GPUArray.zeros(N+1,N+1);

  我們使用gather函數將數據從GPU中轉移回MATLAB工作集;例如:

  vvg = gather(vv);

  需要指出的是這只是將一個數據轉移至GPU,然後從GPU轉移回MATLAB工作集。每個時間步長的所有計算指令都是在GPU上執行的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章