2-3 使用GPU來加速運算

文章推薦指數: 80 %
投票人數:10人

在使用顯卡進行運算時,我們通常必須遵循下列基本步驟:. 使用gpuArray 指令,將MATLAB 工作空間的變數搬移到GPU 的記憶體中。

使用GPU 記憶體中的變數來執行各種在GPU ... 2-3使用GPU來加速運算 GPU(graphicprocessingunits)的出現和普及,可說是近年來科學計算的最大變革,由於GPU具有大量平行處理的能力,所以對於某一些適合平行運算的應用,GPU可說是最是適合不過了。

但是GPU的程式設計,若以C或C++來進行,會比一般程式設計複雜一些,你必須要瞭解GPU本身的設計概念以及硬體結構,才能夠充分發揮GPU的計算能力。

但若要在MATLAB來使用GPU加速各種運算,則是相當容易,因為相關的複雜細節都已經被包含在MATLAB簡單的指令內了。

MATLAB與GPU最相相關的兩個基本指令如下:內測試你的機器有幾張 gpuDeviceCount:可以回傳你的機器上面有幾張GPU卡(或顯卡)。

gpuDevice:可以回傳你的預設GPU卡的相關訊息。

例如,以下範例可以顯示你的機器上有幾張GPU卡,以及預設之GPU卡的相關資訊: Example1:02-程式碼與記憶體之最佳化/gpuDevice01.md=gpuDeviceCount g=gpuDevice d= 1 g= CUDADevicewithproperties: Name:'GeForceGTX970M' Index:1 ComputeCapability:'5.2' SupportsDouble:1 DriverVersion:7 ToolkitVersion:6.5000 MaxThreadsPerBlock:1024 MaxShmemPerBlock:49152 MaxThreadBlockSize:[1024102464] MaxGridSize:[2.1475e+096553565535] SIMDWidth:32 TotalMemory:3.2212e+09 AvailableMemory:2.9349e+09 MultiprocessorCount:10 ClockRateKHz:1038000 ComputeMode:'Default' GPUOverlapsTransfers:1 KernelExecutionTimeout:1 CanMapHostMemory:1 DeviceSupported:1 DeviceSelected:1 在上述範例中,顯示了我的機器只有一張顯卡,並顯示此顯卡的各種相關性質。

在使用顯卡進行運算時,我們通常必須遵循下列基本步驟: 使用gpuArray指令,將MATLAB工作空間的變數搬移到GPU的記憶體中。

使用GPU記憶體中的變數來執行各種在GPU的運算。

使用gather指令,將存放在GPU的變數搬移至MATLAB工作空間中。

在以下範例中,我們以簡單的矩陣相乘來說明如何操作以上這幾個步驟: Example2:02-程式碼與記憶體之最佳化/gpuStep01.ma=rand(100,10000); b=rand(100,10000)'; tic c=a*b; fprintf('CPUtime=%gsec\n',toc); A=gpuArray(a); %PutatoGPU'smemory B=gpuArray(b); %PutbtoGPU'smemory tic C=A*B; %MultiplicationviaGPU fprintf('GPUtime=%gsec\n',toc); c2=gather(C); %PutCtoMATLAB'sworkspace fprintf('isequal(c,c2)=%g\n',isequal(c,c2)); fprintf('Meandeviation=%g\n',mean(mean(abs(c-c2))));CPUtime=0.00463387sec GPUtime=0.000350486sec isequal(c,c2)=0 Meandeviation=5.55428e-13 在上述範例中,我們可以觀察到下列現象: GPU的計算時間(不包含資料搬移的時間)大約只有CPU計算時間的1/20。

GPU計算結果和CPU不完全相同,但兩者的差異性極小。

特別要注意的是,上述GPU的計算時間,並不包含資料搬移時間。

一般而言,我們應該盡量減少資料搬移,並盡量在GPU進行平行運算,否則反而會得不償失。

在前一個範例中,計算加速的幅度和矩陣的維度有很大的關係,下面這個範例將探討這個關係: Example3:02-程式碼與記憶體之最佳化/gpuSpeedup01.mfprintf('computer=%s\n',computer); fprintf('version=%s\n',version); %Speedtest step=10000; colCounts=step*(1:1:20); fori=1:length(colCounts) fprintf('%d/%d\n',i,length(colCounts)); n=colCounts(i); a=rand(100,n); b=rand(100,n)'; myTic=tic;c=a*b;cpuTime(i)=toc(myTic); A=gpuArray(a); B=gpuArray(b); myTic=tic;C=A*B;gpuTime(i)=toc(myTic); end subplot(211);plot(colCounts,cpuTime,'.-',colCounts,gpuTime,'.-'); legend('CPUtime','GPUtime','location','northwest'); title('CPU&GPUtime'); ylabel('Time(sec)'); subplot(212);plot(colCounts,cpuTime./gpuTime,'o-'); title('GPUspeedupratio'); ylabel('Ratios'); xlabel('No.ofcolumns');computer=PCWIN64 version=9.3.0.651671(R2017b)Prerelease 1/20 2/20 3/20 4/20 5/20 6/20 7/20 8/20 9/20 10/20 11/20 12/20 13/20 14/20 15/20 16/20 17/20 18/20 19/20 20/20 在上述範例中,加速幅度很大,GPU速度可達CPU速度的500倍以上。

但請注意,上述範例的計算並不包含資料搬移所需的時間。

Hint請修改上述範例,將資料搬移的時間也算入總計算時間,看看會不會出現「得不償失」的情況。

(待續) MATLAB程式設計:進階篇



請為這篇文章評分?