C.1 研究目的
傳統的電腦中央處理器(CPU)或是數位訊號處理器(DSP)大多為單核架構,對應於 視訊的編碼時也都以序列處理(sequential processing),因此過往的視訊編碼演算法也都是 以序列處理的方式來做編碼。然而NVIDIA 統一運算單元架構(CUDA)則完全的改變了這 樣的運算方式與結構。統一運算單元架構是圖形運算處理器(GPU)的一種延伸架構,因此 也承襲了圖形運算處理器的多核心架構,可同時處理複數筆資料,也就是以平行處理(parallel processing)的方式來提升運算效率。
H.264/AVC 視訊編碼是以宏塊(macroblock)為基本單位,並且使用動作預測(motion estimation)與補償(motion compensation)或是幀內預測(intra-prediction)的方式來降低宏 塊的資訊量,以達到壓縮的效果。其天性非常適合以平行化的方式來做運算,讓不同的宏塊 可以同時的做運算,以提升編碼的速度。因此在本計畫中,我們設計出一套適合於統一運算
單元架構的平行預算編碼演算法,並且實現於NVIDIA 所推出之統一運算單元架構處理器
上。
C.2 文獻探討
傳統用圖形運算處理器處理非圖形運算的技術,統稱為 GPGPU(General-purpose computation on GPUs)[1]。過去也有提出將使用 GPGPU 的技術來加速視訊編碼,如 [2][3][4]。其原理也是將不同宏塊的動作預測利用圖形運算處理器的多重核心來平行處理。
然而過去的圖形運算處理器,其晶片內部缺乏了分享記憶體(shared memory)的機制,因
此運算過程中的暫時資料必須存放於顯示卡上的外部記憶體中(DRAM)。由於視訊壓縮的
資料量非常大,因此資料的傳遞成為一個速度提升的瓶頸。
除此之外,也有相關的論文[5]探討幀內預測的平行演算法,其平行化的方式為將宏塊 中不同的幀內預測模式(四種或九種)同時運算,以提升編碼速度。然而此種方法會沿生 出兩個問題:(1)由於每一個宏塊的預測模式只有四種或九種,但是圖形處理器的核心數 最高可以達到上百個,因此平行化的幅度不夠大,因而導致大部分的處理核心仍然是處於 閒置狀態(idle)。(2)由[6]可得知,不同的幀內預測模式其計算量差異很大,因此不同的 模式同時計算的時候,會導致總預測時間會被計算量最大的幀內預測模式給限制,而導致 效能的提升也受到限制。
由於統一運算單元架構是全新的處理器架構,其應用方式與特性也和過去的圖形運算處理器 有大幅的改變,因此過去所提出之平行演算法亦無法直接應用於統一運算單元架構之上。多 數的演算法必須做大幅度的修正,才能符合統一運算單元架構的應用要求。
C.3 研究方法
在本計畫中,我們首先將H.264/AVC 中計算量最大的兩個部分:動作預測與幀內預測 兩個部分於統一運算單元架構上實現,分別如以下所述:
幀內預測由於每個宏塊的幀內預測是使用該宏塊鄰近已編碼完成並解碼回來的宏塊,來做預測,
因此宏塊與宏塊間會產生依賴性(inter-block dependency),若要每個宏塊平行做運算的 話,會導致預測所需的像素(pixel)尚未運算完成的情況。為了解決這個問題,我們提 出使用原始影像來做幀內預測的演算法,也就是在預測宏塊資料的時候使用原始的像素 資料來做計算並且比較每個模式的SAD(sum of absolute difference),以找到SAD 最小 的模式。因此每個宏塊便可以同時的做預測並且產生出最好的模式。而最後實際在編碼 的時候,再使用重建後的資料來做編碼。如Fig. C-1之流程圖所示。
動作預測為了符合統一運算單元架構的特性,我們設計了一套五個步驟的全域搜尋(full search)
演算法,並且包含了H.264/AVC 編碼標準中所具備的多重方塊大小動作補償(variable block size motion estimation),而動作向量(motion vector)精細度達到四分之一像素。
五個步驟如Fig. C-2所示。在此演算法之中,我們對於記憶體的配置與使用做了最佳化,
讓運算中的暫時資料可以在處理器中的分享記憶體儲存並且重複利用,以節省處理器與 外部記憶體間的頻寬使用量。
Fig. C-1. 使用原始影像作幀內預測之演算法流程圖
6
Fig. C-2 五個步驟的動作預測流程圖
C.4 結果與討論
使用原始影像作幀內預測,雖然可以達成宏塊的平行化,然而卻會因為預測資料與實際 資料的不相同,會導致編碼效能下降,如Fig. C-3。由於在一般的應用之下,使用幀內預測 與使用動作預測的比例差距很大,大部分的宏塊都會使用動作預測來做編碼,因此使用原始 影像作幀內預測的效能下降有限,甚至在大部分的測試影像中,其編碼效能可以逼近使用重 建影像作幀內預測的演算法。
而使用平行化的動作預測時,由於每個預測方塊之動作向量預測子(motion vector predictor)需要設置為零,才能消除每個預測方塊之宏塊間依賴性,因此編碼效能也會有些 許的下降,如Fig. C-3。
我們所使用的測試平台如Table C-1所示,統一運算單元架構處理器本質上也是一個顯示 晶片,因此是建立在個人電腦上,而在需要使用顯示晶片運算的時候,資料會從個人電腦的 記憶體中傳送至顯示卡上的記憶體。而運算完畢之後,也是將資料從顯示卡上的記憶體傳送 回個人電腦之記憶體中。使用統一運算單元架構來處理幀內預測與動作預測的如Table C-2 與Fig. C-4所示,在這兩個部分之中分別都可以達到近 12 倍的加速。另外在幀內預測中若只
使用單一個核心來做編碼,其處理時間會比只使用個人電腦來做運算慢了500 倍,因此只若
使用統一運算單元架構卻沒有搭配對應的平行編碼演算法,不但無法有效的做加速,反而會 拖慢整體的運算時間。
Fig. C-3. 使用平行演算法與原始編碼演算法之效能比較
Fig. C-4. 動作偵測於統一運算單元架構之加速效果
8
Table C-1 統一運算單元架構測試平台
CPU AMD Athlon 64X2 2.1GHz
memory 2,048MB
OS Microsoft Windows XP sp2 PC
Compiler Microsoft Visual Studio 2005 NVIDIA GeForce 8800GTX Core Clock 575MHz Processor numbers 128
Memory Clock 900MHz
Memory 768MB
GPU
Memory Bandwidth 86.4(GB/sec) CUDA Toolkit and SDK 1.1
CUDA
NVIDIA Driver for Microsoft Windows XP with CUDA Support (169.09).
Table C-2 幀內預測於統一運算單元架構之加速效果
PC (msec) CUDA (msec) Speed up CUDA using one thread(msec)
Intra_16x16 4.06 0.63 6.4x 265
Intra_4x4 15.94 0.92 17.3x 753
Intra_chroma 2.19 0.31 7.1x 93
Total 22.19 1.86 11.9x 1112