SIMD數據並行(二)——多媒體SIMD擴展指令集


 

在計算機體系中,數據並行有兩種實現路徑:MIMD(Multiple Instruction Multiple Data,多指令流多數據流)和SIMD(Single Instruction Multiple Data,單指令流多數據流)。其中MIMD的表現形式主要有多發射、多線程、多核心,在當代設計的以處理能力為目標驅動的處理器中,均能看到它們的身影。同時,隨着多媒體、大數據、人工智能等應用的興起,為處理器賦予SIMD處理能力變得愈發重要,因為這些應用存在大量細粒度、同質、獨立的數據操作,而SIMD天生就適合處理這些操作。

 

SIMD結構有三種變體:向量體系結構、多媒體SIMD指令集擴展和圖形處理單元。本文集中圍繞多媒體SIMD指令集擴展進行描述。


多媒體SIMD指令集擴展

1. 簡介

上世紀90年代,隨着互聯網的普及,音頻、圖片、視頻等多媒體應用迅速崛起,為應對多媒體密集的計算需求,Intel於1996年率先將多媒體SIMD擴展指令集引入通用處理器,在其奔騰處理器上集成了 SIMD 擴展部件 MMX。

 

多媒體應用中通常存在大量同質、獨立的訪存和計算操作,且使用的數據類型一般都很窄(如圖形系統使用8位表示三基色的每一種顏色,使用8位表示透明度;音頻采樣位寬通常為8位或16位)。SIMD擴展指令集具有獨立的長位寬向量寄存器(64/128/256/512/1024......),允許將原來需要多次裝載的連續內存地址數據一次性裝載到向量寄存器中,並使用分裂模式將長的向量寄存器當作多個獨立的窄位寬元素,通過一條SIMD擴展指令實現對SIMD向量寄存器中所有數據元素的並行處理。這種執行方式非常適合於處理計算密集、數據相關性少的音視頻解碼等多媒體程序。

 

SIMD擴展部件僅需要在原來標量部件的基礎上復制幾份同樣的處理單元,不需要增加太多的額外硬件,就能對多媒體等特定應用帶來顯著的性能提升,且不增加通信以及cache和內存的開銷,因此即使在多核時代,SIMD擴展部件仍然是程序加速的重要手段之一。

 

2. 實現形式

寄存器分裂:將長向量寄存器的比特位均勻“分裂”成多個窄位寬(8/16/32/64)元素,當作獨立數據進行操作。一般的多媒體SIMD擴展指令集均支持定點的有符號和無符號數據操作,部分處理器支持單、雙精度的浮點操作。

 

下圖舉了一個128位寬寄存器的例子:

圖1 將128位寬的寄存器分裂成4個32位單精度浮點寄存器或16個8位寬有符號定點寄存器

 

並行車道:SIMD擴展部件負責訪存、計算等操作的功能單元均支持多個並行子單元的同時處理,因此一條SIMD擴展指令可一次性操作多個元素。

 

下圖顯示了一個功能單元以四車道並行執行的例子:

圖2 SIMD多媒體擴展指令執行示意圖

 

3. 主要特征

SIMD擴展指令在實現機制上與普通的標量指令沒有太多差別。在SIMD擴展指令集上均可以實現標量指令集支持的各種操作,如存取操作、算數運算、邏輯運算、比特操作,以及常用的飽和處理、四舍五入、條件執行等功能。

 

SIMD擴展指令特殊之處在於並行元素的處理。除部分計算子單元支持條件執行外,各子單元的訪存和計算操作都將嚴格同步執行,一方面迫使使用它的程序需要具備可並行化的特征,另一方面帶來訪存上的一些問題。

 

當需要並行處理的元素個數小於一條SIMD擴展指令所能支持的並行操作個數,或是面臨非連續訪存的並行處理需求時,強行使用SIMD擴展指令可能會帶來內存越界的問題。早期的SIMD向量存取指令只能訪問在內存中連續對齊的數據,因此當程序中存在不對齊或不連續內存引用時,需要通過移位或者重組等輔助指令才能組成向量。在向量重組指令能力較弱或者根本不支持向量重組指令時,強制將不連續的訪存數據組成向量可能帶來大的開銷,甚至導致向量化沒有收益。

 

但隨着處理器技術的發展,目前已有處理器已經能支持非對齊的訪存操作,並添加了大量用於數據重組的指令,部分處理器還支持集散(gather-scatter)內存訪問,這給SIMD向量化發掘提供了堅實的基礎。

 

SIMD擴展指令集支持的計算功能也在不斷豐富,如今很多處理器支持的SIMD擴展指令達上百條之多。很多指令的設計初衷早已跨越多媒體應用處理范疇,延伸到信號處理、科學計算等需要高性能計算能力的領域。


在各處理器上的應用情況

Intel對多媒體SIMD擴展指令集的應用很具代表性。1996 年,Intel 在其奔騰處理器上集成了 SIMD 擴展部件 MMX,其向量寄存器為64位寬。后來又相繼推出了 SSE(128位寬),AVX(256位寬),IMCI 和 AVX-512(512位寬)。

 

圖3 Intel x86處理器的多媒體SIMD擴展指令集演進歷程

 

其他 SIMD 擴展部件還包括摩托羅拉 PowerPC 處理器的 AltiVec、Sun 公司 SPARC 處理器中的 VIS、HP 公司 PA-RISC 處理器中的 MAX、DEC 公司 Alpha 處理器中的 MVI-2、MIPS公司 V 處理器中的 MDMX、AMD處理器中的3DNow!、ARM內核中的NEON、CEVA公司的VCU 等。

 

SIMD 擴展部件最初僅用於多媒體領域和數字信號處理器中,后來,研究人員將SIMD 擴展部件應用到高性能計算機中,如,IBM 的超級計算機 BlueGene/L 和國產的神威藍光超級計算機中都集成短向量擴展部件。國產處理器中,龍芯、邁創以及魂芯一號都含有 SIMD 擴展部件。

 

圖4 帶有SIMD擴展部件的處理器

 

很多通用指令集也支持SIMD形式的訪存和計算操作,但它們支持的寄存器位寬有限,通過將通用寄存器(32/16位寬)分裂成16/8位的更小單元進行獨立的並行操作,如ARM指令集、TIC64X指令集,等。這種SIMD指令在實現機制上和多媒體SIMD擴展指令並無多少區別,不過考慮到多媒體SIMD擴展指令集針對特殊應用場景而“擴展”的用意,還是暫不把他們歸為多媒體SIMD擴展指令。


如何發揮SIMD擴展指令集的效能

多媒體SIMD擴展指令集必須要有軟件的支持。與標量部件相比,SIMD擴展部件的收益來自於向量運算和向量訪存。因此將程序盡可能向量化成SIMD指令可執行的形式,是提高SIMD整體效益的關鍵。

 

對於軟件開發者而言,有大概5種方式來利用多媒體SIMD擴展指令集的並行加速功能:

  1. 使用匯編語言編寫代碼。包括在匯編源文件中書寫匯編指令,或是在高級語言中嵌入擴展匯編;

  2. 使用內嵌指令函數。一般SIMD擴展指令集設計商都會提供各匯編指令的封裝函數,編程者只需調用這些函數就能實現匯編指令的插入,將復雜的寄存器分配的任務交給編譯器來完成;

  3. 使用C++類庫擴展。這種高級語言提供的類庫將偏處理器底層的信息封裝起來,留給編程者更接近行為體驗的語法和函數接口;

  4. 使用庫函數。SIMD擴展指令集設計商往往會公開一些典型應用的庫函數,這些庫函數一般充分挖掘了指令集的特性,效率很高;

  5. 使用編譯制導語句輔助編譯器優化。現今的主流編譯器集成有自動向量化算法,能夠在編譯期間分析代碼的可並行性,並生成SIMD擴展匯編指令。不過由於編譯器能夠從代碼中提取的信息有限,對一些復雜的處理過程,即使存在並行開發的可能,編譯器也可能無法成功向量化。編譯制導語句可以從開發者的角度提供給編譯器更多編譯期間無法提取的信息,提高編譯器將代碼向量化的概率。如OpenMP和OpenACC就支持通過添加編譯指示的方式發掘程序的SIMD並行性.

 

另外,由於很多SIMD擴展指令一般都是在一個周期內發出,但是執行結果可能若干個周期才能有效。在做循環的優化中,如果能結合循環展開方式開發軟件流水線代碼,可以減少由於前后指令相關造成的延遲等待時間,盡可能地挖掘處理器的峰值效率。

 

處理非整數倍並行長度的應用

在開發中,很容易碰到這樣的情況:要對一段具有N並行度的代碼進行向量化,已知SIMD擴展指令一次可處理8個這樣的元素,但N在編譯時未知。這時,應該如何通過手動向量化的方法來編寫代碼呢?

 

一種方法就是人為將N擴展為8的整數倍,如N = (N+7)/8,然后進行向量化。這樣編寫起來很方便,帶來的問題就是需要預留足夠的內存空間,否則容易引起內存越界。

 

這里主要介紹一種不需要人為擴展內存邊界的方法。假設我們要處理的代碼是:

for(i=0; i<N; i++)

{

    a[i] = b[i] + c[i];

}

 

可以這樣編寫SIMD擴展指令向量化的代碼:

v_len = N/8;

for(i=0; i<v_len; i++)

{

    v_b = vload(&b[8*i]);

    v_c = vload(&c[8*i]);

    v_a = vadd(v_b, v_c);

    vstore(&a[8*i]);

}

/***收尾處理***/

v_b = vload(&b[N-8]);

v_c = vload(&c[N-8]);

v_a = vadd(v_b, v_c);

vstore(&a[N-8]);

 

這種方式通過將尾部不足向量長度的元素與前幾個元素拼湊成一組整的向量,實現收尾處理,將不會帶來內存越界的問題。不過這種方式也有不足之處,就是代碼體積將增大一倍左右,且不能處理N小於向量長度的情況。

 


參考資料

【1】高偉, 趙榮彩, 韓林, 龐建民, 丁銳. SIMD自動向量化編譯優化概述[J].軟件學報,2015, 26(6): 1265-1284.

【2】John L. Hennessy,David A. Patterson . 計算機體系結構:量化研究方法:第5版[M].北京:人民郵電出版社,2013. (原名《Computer Architecture:A Quantitative Approach》)

【3】David A. Patterson,John L. Hennessy . 計算機組成與設計:硬件/軟件接口:第5版[M].北京:機械工業出版社,2015. (原名《Computer Organization and Design:The Hardware/Software Interface》)

 

 

·END·

 


 

你可能還感興趣:

SIMD數據並行(一)——向量體系結構

計算機系統中與存儲有關的那些事

現代處理器與代碼性能優化

《大話處理器》筆記摘抄及一點延伸

翻譯 | 指令調度基礎

翻譯 | 淺析算法復雜度分析

關於代碼執行效率優化的一次內部分享

 

歡迎來我的微信公眾號做客:信號君

專注於信號處理知識、高性能計算、現代處理器&計算機體系 

 

技術成長 | 讀書筆記 | 認知升級

幸會~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM