卷積操作的GPU粗粒度並行實現及測試
一、 算法基本思想:
1、 GPU中的一個線程產生一個卷積結果,有多少個結果就使用多少個Block;
2、 矩陣和卷積核存放在共享內存中,卷積結果存放在全局內存中;
3、 支持10000以內任意維度的二維矩陣,卷積核最大支持16x16。
4、 支持任意多幅圖像的批處理。
二、 實驗平臺:
CPU:Intel(R) Xeon(R) E5-2650 0 @2.00GHz 16核 32線程
GPU:NVIDIA Tesla C2070(見下表)
RAM Memory:64G
Operating System:64bit Win7。
尺寸規格 |
9.75英寸PCIe x16規格 |
Tesla GPU的數量 |
1 |
CUDA核心數量 |
448 |
CUDA核心頻率 |
1.15 GHz |
雙精度浮點性能(峯值) |
515 Gflops |
單精度浮點性能(峯值) |
1.03 Tflops |
專用存儲器總容量* Tesla C2050 |
3GB GDDR5 |
存儲器頻率 |
1.5 GHz |
存儲器接口 |
384位 |
存儲器帶寬 |
144 GB/秒 |
功耗 Tesla C2050 |
238W熱設計功耗 |
系統接口 |
PCIe x16 Gen2 |
散熱解決方案 |
主動式風扇散熱器 |
顯示器支持 Dual-Link DVI-I |
|
軟件開發工具 |
CUDA C/C++/Fortran、OpenCL以及DirectCompute工具包。 |
三、 CPU和GPU耗時比較
說明:在CPU實現中,不做任何優化,卷積操作使用基本的四層循環形式。爲了程序了通用性,在GPU內部做了很多的條件測試,比較耗時。這個是初始版,可以做進一步優化,比如一些字節對齊等。
測試時間說明:使用clock()進行測試,精度爲0.001秒(1ms),GPU測試的總時間包括函數調度開銷、GPU啓動開銷、設備內存的申請釋放開銷、數據傳輸開銷和計算開銷等,並且測試了數據的預處理和後處理的時間消耗。CPU只有函數調度開銷和計算開銷。
誤差說明:CPU和GPU均使用float型數組存儲數據,矩陣和卷積核數據隨機初始化,並對CPU和GPU卷積結果作比較,測試卷積的有效性。
初步分析:
A. CPU和GPU卷積結果誤差爲0,表明GPU實現是有效的。
B. 矩陣和卷積核較小時,CPU性能較好。矩陣和卷積核較大時,GPU性能較高,體現出GPU的並行性,能快速處理大規模、高吞吐量的數據。當數據量不是很大時,GPU耗時主要是啓動開銷,即設備內存的分配開銷。
C. GPU上,一個線程產生一個卷積結果,在線程內部是串行的,卷積核越大,單個卷積結果越耗時。
爲了減少訪問全局內存的次數,運算前,矩陣和卷積核拷貝到Block內部的共享內存中。
使用二維Block,一個Block內部16x16個線程,產生多少個卷積結果就使用多少個Block,因此固定卷積核,改變矩陣大小,運行時間基本不變,當矩陣過大時,使用的Block數量過多時,運算時間受限於GPU硬件中支持的SM和Block數量。(考慮卷積程序的通用性,數據拷貝時使用了比較多的條件測試和分支操作,性能受一定影響)。
D. CPU上是簡單的串行運算,受矩陣和卷積核大小影響較大。
E. 當矩陣兩個維度都超過10000時,CPU運算出現指針異常,可能是矩陣較大時(550MB左右),數據存儲時不再連續,指針溢出。所以無法測試。
Matrix Size |
Number |
Kernel |
CPU(s) |
CPU2GPU |
GPU-Kernel |
GPU2CPU |
5x4 |
1 |
5x4 |
<1ms |
<1ms |
<1ms |
<1ms |
12x9 |
1 |
5x4 |
<1ms |
<1ms |
<1ms |
<1ms |
1 |
5x4 |
<1ms |
<1ms |
<1ms |
<1ms |
|
118x29 |
1 |
5x4 |
<1ms |
<1ms |
<1ms |
<1ms |
138x59 |
1 |
5x4 |
<1ms |
<1ms |
<1ms |
<1ms |
158x159 |
1 |
5x4 |
0.003 |
<1ms |
0.001 |
<1ms |
558x559 |
1 |
5x4 |
0.044 |
0.001 |
0.001 |
<1ms |
1128x1159 |
1 |
5x4 |
0.157 |
0.002 |
0.004 |
0.001 |
2128x2159 |
1 |
5x4 |
0.442 |
0.007 |
0.012 |
0.007 |
5128x5159 |
1 |
5x4 |
2.394 |
0.038 |
0.068 |
0.035 |
18128x4159 |
1 |
5x4 |
6.866 |
0.111 |
0.193 |
0.114 |
10128x11159 |
1 |
5x4 |
10.074 |
0.160 |
0.288 |
0.142 |
|
|
|
|
|
15.54Gflops |
1.427GBps |
5x4 |
1 |
14x15 |
~ |
~ |
~ |
~ |
12x9 |
1 |
14x15 |
~ |
~ |
~ |
~ |
18x19 |
1 |
14x15 |
<1ms |
<1ms |
<1ms |
<1ms |
118x29 |
1 |
14x15 |
<1ms |
<1ms |
<1ms |
<1ms |
138x59 |
1 |
14x15 |
<1ms |
0.001 |
<1ms |
<1ms |
158x159 |
1 |
14x15 |
0.024 |
<1ms |
<1ms |
<1ms |
558x559 |
1 |
14x15 |
0.354 |
<1ms |
0.006 |
0.001 |
1128x1159 |
1 |
14x15 |
1.400 |
0.002 |
0.023 |
0.002 |
2128x2159 |
1 |
14x15 |
3.839 |
0.007 |
0.082 |
0.007 |
5128x5159 |
1 |
14x15 |
22.856 |
0.042 |
0.475 |
0.035 |
11128x4159 |
1 |
14x15 |
38.172 |
0.079 |
0.833 |
0.061 |
10128x11159 |
1 |
14x15 |
122.679 |
0.203 |
2.614 |
0.358 |
|
|
|
|
|
23.23Gflops |
382.6MBps |
5x4 |
15 |
14x15 |
~ |
~ |
~ |
~ |
12x9 |
15 |
14x15 |
~ |
~ |
~ |
~ |
18x19 |
15 |
14x15 |
0.001 |
<1ms |
<1ms |
<1ms |
118x29 |
15 |
14x15 |
0.041 |
<1ms |
0.001 |
<1ms |
138x59 |
15 |
14x15 |
0.097 |
<1ms |
0.002 |
<1ms |
158x159 |
15 |
14x15 |
0.372 |
0.001 |
0.007 |
<1ms |
558x559 |
15 |
14x15 |
4.943 |
0.006 |
0.084 |
0.006 |
1128x1159 |
15 |
14x15 |
15.851 |
0.030 |
0.353 |
0.028 |
2128x2159 |
15 |
14x15 |
57.699 |
0.097 |
1.247 |
0.084 |
3158x3059 |
15 |
14x15 |
121.152 |
0. 201 |
2.624 |
0.192 |
5128x5159 |
15 |
14x15 |
指針溢出 |
|||
11128x4159 |
15 |
14x15 |
||||
10128x11159 |
15 |
14x15 |
||||
|
|
|
|
|
23.01Gflops |
362.9MBps |
進一步分析:
從上表可知,最高吞吐率爲1.427GBps,PCAIE總線的帶寬爲5GBps,還有一定的空間。單精度浮點數乘法的最高有效計算性能爲23.23Gflops,官方文檔上標示的最高單精度浮點性能爲1Tflops,差別較大,分析原因如下:
A. CPU傳輸給GPU的數據是一維數組,而在GPU內部是按二維進行運算的,在存取數據是需要做很多的地址計算操作。
B. 由於卷積特有的性質,數據有很多的重複性,將大圖像分割成很多小的圖像塊時,需要考慮邊界問題,並且爲了保證程序的通用性,支持任意的圖像和卷積核大小,以及支持任意多幅圖像的批處理,GPU中,將數據拷貝到共享內存之前,做了比較多的條件測試,時間消耗比較大。這個地方可以通過在CPU進行邊界擴展等預處理,進一步提高GPU運算性能。
C. 線程內部計算單個卷積結果時,使用了一個二維循環,當卷積核較大時,運算時間呈指數型增長。
總結:
寫一個GPU程序簡單,寫一個高效的GPU程序難,而寫一個高效的通用性的GPU程序,更難,需要考慮方方面面的東西。目前版本的程序,僅僅具有簡單的通用性,因爲使用基本的數據結構保存數據,當數據量達到500MB時,很容易出現問題,而且計算效率也不是很高。
下週工作計劃:
(1) 在CPU中做一些數據的預處理,考慮字節對齊,邊界填充等,儘量減少GPU內部的條件測試。考慮將單個的卷積操作拆開,實現細粒度並行,提高單個卷積結果的計算效率。
(2) 學習三維Block,將一幅圖像放在第一和第二維度上,批處理圖像放在第三個維度,減少後處理計算量,增加批處理圖像的卷積計算性能。
(3) 考慮反捲積運算的並行化。考慮將CUDA卷積程序與matlab版的CNN結合,進行交叉編譯,提高CNN的運算效率。