一、SIMD
ARM NEON 是適用于 ARM Cortex-A 和 Cortex-R 系列處理器的一種SIMD(Single Instruction Multiple Data)擴(kuò)展架構(gòu)。 ? SIMD?采用一個(gè)控制器來(lái)控制多個(gè)處理器,同時(shí)對(duì)一組數(shù)據(jù)(又稱(chēng)“數(shù)據(jù)向量”)中的每個(gè)數(shù)據(jù)分別執(zhí)行相同操作,從而實(shí)現(xiàn)并行技術(shù)。 ? SIMD?特別適用于一些常見(jiàn)的任務(wù),如音頻圖像處理。大部分現(xiàn)代 CPU 設(shè)計(jì)都包含了 SIMD 指令,來(lái)提高多媒體使用的性能。 ?
SIMD 操作示意圖 ? 如上圖所示,標(biāo)量運(yùn)算時(shí)一次只能對(duì)一對(duì)數(shù)據(jù)執(zhí)行乘法操作,而采用 SIMD 乘法指令,則一次可以對(duì)四對(duì)數(shù)據(jù)同時(shí)執(zhí)行乘法操作。 ?
A. 指令流與數(shù)據(jù)流
費(fèi)林分類(lèi)法根據(jù)指令流(Instruction)和數(shù)據(jù)流(Data)的處理方式進(jìn)行分類(lèi),可分成四種計(jì)算機(jī)類(lèi)型: ?
費(fèi)林分類(lèi)示意圖
1. SISD(Single Instruction Single Data)
機(jī)器的硬件不支持任何形式的并行計(jì)算,所有的指令都是串行執(zhí)行。單個(gè)核心執(zhí)行單個(gè)指令流 , 操作存儲(chǔ)在單個(gè)內(nèi)存中的數(shù)據(jù) , 每次一個(gè)操作。早期的計(jì)算機(jī)都是SISD機(jī)器,如馮諾.依曼架構(gòu),IBM PC機(jī)等。 ?
2. MISD(Multiple Instruction Single Data)
是采用多個(gè)指令流來(lái)處理單個(gè)數(shù)據(jù)流。由于實(shí)際情況中,采用多指令流處理多數(shù)據(jù)流才是更有效的方法,因此MISD只是作為理論模型出現(xiàn),沒(méi)有投入到實(shí)際應(yīng)用之中。
3. MIMD(Mutiple Instruction Mutiple Data)
計(jì)算機(jī)具有多個(gè)異步和獨(dú)立工作的處理器。在任何時(shí)鐘周期內(nèi),不同的處理器可以在不同的數(shù)據(jù)片段上執(zhí)行不同的指令,也即是同時(shí)執(zhí)行多個(gè)指令流,而這些指令流分別對(duì)不同數(shù)據(jù)流進(jìn)行操作。MIMD架構(gòu)可以用于諸如計(jì)算機(jī)輔助設(shè)計(jì)、計(jì)算機(jī)輔助制造、仿真、建模、通信交換機(jī)的多個(gè)應(yīng)用領(lǐng)域。 ? 除了以上模型外,由NVIDIA公司生產(chǎn)的GPU引入SIMT體系結(jié)構(gòu):
4. SIMT(Single Instruction Multiple Threads)
類(lèi)似 CPU 上的多線程,所有的核心各有各的執(zhí)行單元,數(shù)據(jù)不同,執(zhí)行的命令是相同的。多個(gè)線程各有各的處理單元,和 SIMD 共用一個(gè) ALU 不同。 ?
SIMT 示意圖
B. SIMD 特點(diǎn)及發(fā)展趨勢(shì)
1. SIMD 優(yōu)勢(shì)與不足
2. SIMD發(fā)展趨勢(shì)
以ARM架構(gòu)下的下一代 SIMD 指令集SVE(Scalable Vector Extension,可擴(kuò)展矢量指令)為例,其是_針對(duì)高性能計(jì)算(HPC)和機(jī)器學(xué)習(xí)等領(lǐng)域開(kāi)發(fā)的一套全新的矢量指令集_。 ? SVE 指令集中有很多概念與 NEON 指令集類(lèi)似,例如矢量、通道、數(shù)據(jù)元素等。 ? SVE指令集也提出了一個(gè)全新的概念:可變矢量長(zhǎng)度編程模型。
? SVE 可擴(kuò)展模型 ? 傳統(tǒng)的 SIMD 指令集采用固定大小的向量寄存器,例如 NEON 指令集采用固定的 64/128 位長(zhǎng)度的矢量寄存器。 ? 而支持 VLA 編程模型的 SVE 指令集則支持可變長(zhǎng)度的矢量寄存器。因此允許芯片設(shè)計(jì)者根據(jù)負(fù)載和成本來(lái)選擇一個(gè)合適的矢量長(zhǎng)度。 ? SVE指令集的矢量寄存器的長(zhǎng)度最小支持 128 位,最大可以支持 2048 位,以 128 位為增量。SVE 設(shè)計(jì)確保同一個(gè)應(yīng)用程序可以在支持不同矢量長(zhǎng)度的 SVE 指令機(jī)器上運(yùn)行,而不需要重新編譯代碼。 ? ARM 在 2019 年便推出了 SVE2,以最新的 Armv9 為基礎(chǔ),擴(kuò)充了更多的運(yùn)算類(lèi)型以全面替代 NEON,同時(shí)增加了矩陣相關(guān)運(yùn)算的支持。 ?
二、 ARM 的 SIMD 指令集
1. ARM 處理器的 SIMD 支持 - NEON
ARM NEON 單元默認(rèn)包含在 Cortex-A7 和 Cortex-A15 處理器中,但在其他 ARMv7 Cortex-A 系列處理器中是可選的,某些實(shí)現(xiàn) ARMv7–A 或 ARMv7–R 架構(gòu)配置文件的Cortex-A 系列處理器可能不包含NEON單元。 ? 符合 ARMv7 的內(nèi)核的可能組合有以下四種: ?
? ? 因此必須首先確認(rèn)處理器是否支持 NEON 和 VFP??梢栽诰幾g和運(yùn)行的時(shí)候進(jìn)行檢查。 ?
? NEON 發(fā)展史
2. ARM 處理器的 SIMD 支持檢查
2.1 編譯階段檢查
檢測(cè) NEON單元是否存在的最簡(jiǎn)單方法。在 ARM 編譯器工具鏈(armcc)v4.0 及更高版本或 GCC 中,檢查預(yù)定義宏?ARM_NEON?或者?__arm_neon?是否開(kāi)啟。 armasm?等效的預(yù)定義宏是?TARGET_FEATURE_NEON。
2.2 運(yùn)行階段檢查
在運(yùn)行時(shí)檢測(cè) NEON 單元需要操作系統(tǒng)的幫助。ARM 架構(gòu)有意不向用戶模式應(yīng)用程序公開(kāi)處理器功能。在Linux下,/proc/cpuinfo?以可讀的形式包含此信息,比如:
在Tegra(帶有FPU的雙核Cortex-A9處理器)??
$ /proc/cpuinfo swp half thumb fastmult vfp edsp thumbee vfpv3 vfpv3d16
帶有 NEON 單元的 ARM Cortex-A9 處理器
$ /proc/cpuinfo swp half thumb fastmult vfp edsp thumbee neon vfpv3? ? ? 由于/proc/cpuinfo?輸出是基于文本的,因此通常首選查看輔助向量?/proc/self/auxv,其包含二進(jìn)制格式的內(nèi)核?hwcap,可以輕松地在?/proc/self/auxv?文件中搜索?AT_HWCAP?記錄,以檢查?HWCAP_NEON?位(4096)。 ? 某些 Linux 發(fā)行版ld.so?鏈接器腳本被修改為通過(guò) glibc 讀取?hwcap?,并為啟用 NEON 的共享庫(kù)添加額外的搜索路徑。??
3. 指令集關(guān)系
在ARMv7中,NEON 與 VFP 指令集具有以下關(guān)系:
具有 NEON 單元但沒(méi)有VFP單元的處理器無(wú)法在硬件中執(zhí)行浮點(diǎn)運(yùn)算。
由于 NEON SIMD 操作更有效地執(zhí)行向量計(jì)算,因此從 ARMv7 的引入開(kāi)始,VFP 單元中的向量模式操作已被棄用。因此,VFP 單元有時(shí)也稱(chēng)為浮點(diǎn)單元(FPU)。
VFP 可以提供完全兼容 IEEE-754 的浮點(diǎn)運(yùn)算,_ARMv7 NEON 單元中的單精度運(yùn)算不完全符合 IEEE-754_。
NEON不能取代 VFP。VFP 提供了一些在 NEON 指令集中沒(méi)有等效實(shí)現(xiàn)的專(zhuān)用指令。
半精度指令僅適用于包含半精度擴(kuò)展的 NEON 和 VFP 系統(tǒng)。
在ARMv8中,VFP已被NEON取代,以上問(wèn)題如 NEON 并不完全符合 IEEE 754 標(biāo)準(zhǔn),并且有一些指令 VFP 支持而 NEON 不支持的問(wèn)題已在 ARMv8 中得到解決。
三、NEON
NEON 是適用于 ARM Cortex-A 系列處理器的一種128位 SIMD 擴(kuò)展結(jié)構(gòu),每個(gè)處理器核心均有一個(gè) NEON 單元,因此可以實(shí)現(xiàn)多線程并行的加速效果。 ?
1. NEON基本原理
1.1 NEON 指令執(zhí)行流程
? 上圖為 NEON 單元完成加速計(jì)算的流程圖。其中向量寄存器中的每個(gè)元素同步執(zhí)行計(jì)算,以此來(lái)加速計(jì)算過(guò)程。 ?
1.2 NEON 計(jì)算資源
NEON 與 ARM 處理器資源關(guān)系
- NEON 單元作為 ARM指令集的擴(kuò)展,使用獨(dú)立于 ARM 原有寄存器的 64位 或 128 位寄存器進(jìn)行 SIMD 處理,在 64位 寄存器的寄存器文件上運(yùn)行。- NEON 和 VFP 單元完全集成到了處理器中,并共享處理器資源以進(jìn)行整數(shù)運(yùn)算、循環(huán)控制和緩存。與硬件加速器相比,這顯著降低了面積和功耗成本。并且其還使用更簡(jiǎn)單的編程模型,因?yàn)镹EON 單元使用與應(yīng)用程序相同的地址空間。 ?
NEON 與 VFP 資源關(guān)系
NEON 寄存器與 VFP 寄存器重疊,ARMv7 有 32 個(gè) NEON D 寄存器,如下圖所示。 ?
NEON 寄存器
2. NEON指令
2.1 自動(dòng)矢量化
向量化編譯器可以使用 C 或 C++ 源代碼,以一種能夠有效使用 NEO N硬件的方式對(duì)其進(jìn)行矢量化。這意味著可以通過(guò)編寫(xiě)可移植的 C 代碼,同時(shí)仍然可以獲得 NEON 指令所帶來(lái)的性能水平。 ? 為了幫助矢量化,將循環(huán)迭代次數(shù)設(shè)為矢量長(zhǎng)度的倍數(shù)。GCC 和 ARM 編譯器工具鏈都具有為 NEON 技術(shù)啟用自動(dòng)矢量化的選項(xiàng)。
2.2 NEON匯編
對(duì)于性能要求特別高的程序,手工編寫(xiě)匯編代碼是更適合的方式。 ? GNU 匯編器(gas) 和 ARM Compile r工具鏈匯編器(armasm)都支持 NEON 指令的匯編。 ? 編寫(xiě)匯編函數(shù)時(shí),需要了解ARM EABI,其定義了如何使用寄存器。ARM嵌入式應(yīng)用程序二進(jìn)制接口(EABI)指定哪些寄存器用于傳遞參數(shù)、返回結(jié)果或必須保留,指定了除ARM內(nèi)核寄存器之外的32個(gè)D寄存器的使用。下圖對(duì)寄存器功能進(jìn)行了總結(jié)。 ?
? 寄存器功能
2.3 NEON Intrinsics
NEON intrinsic 函數(shù)提供了一種編寫(xiě) NEON 代碼的方法,該方法比匯編代碼更易于維護(hù),同時(shí)仍然可以控制生成的 NEON 指令。 ? 內(nèi)部函數(shù)使用與 D 和 Q NEON 寄存器對(duì)應(yīng)的新數(shù)據(jù)類(lèi)型。數(shù)據(jù)類(lèi)型支持創(chuàng)建直接映射到NEON 寄存器的 C 變量。 ? NEON intrinsic 函數(shù)的編寫(xiě)類(lèi)似于使用這些變量作為參數(shù)或返回值的函數(shù)調(diào)用。編譯器做了一些通常與編寫(xiě)匯編語(yǔ)言相關(guān)的繁重工作,例如: 寄存器分配代碼調(diào)度或重新排序指令。 ?
intrinsic 缺點(diǎn)
無(wú)法讓編譯器準(zhǔn)確輸出想要的代碼,因此在轉(zhuǎn)向NEON匯編代碼時(shí)仍有一些改進(jìn)的可能性。 ?
NEON 指令簡(jiǎn)類(lèi)型
NEON 數(shù)據(jù)處理指令可以分為正常指令、長(zhǎng)指令、寬指令、窄指令和飽和指令。以 Intrinsic 的長(zhǎng)指令為例?int16x8_t vaddl_s8(int8x8_t __a, int8x8_t __b);- 上面的函數(shù)將兩個(gè)64位的 D 寄存器向量(每個(gè)向量包含8個(gè)8位數(shù)字)相加,生成一個(gè)包含8個(gè)16位數(shù)字的向量(存儲(chǔ)在128位的Q寄存器中),從而避免相加的結(jié)果溢出。
四、其他 SIMD 技術(shù)
1. 其他平臺(tái)上的 SIMD 技術(shù)
SIMD 處理不是 ARM 獨(dú)有的,下圖將其與 x86 和 Altivec 進(jìn)行了比較。 ?
? SIMD 對(duì)比
2. 與專(zhuān)用 DSP 對(duì)比
許多基于 ARM 的 SOC 中還包含 DSP 等協(xié)處理硬件,因此可以同時(shí)包含 NEON 單元和DSP。相對(duì)于 DSP,NEON 的特點(diǎn)有:
四、總結(jié)
本節(jié)主要介紹基本 SIMD 及其他的指令流與數(shù)據(jù)流的處理方式,NEON 的基本原理、指令以及與其他平臺(tái)及硬件的對(duì)比。 ?
編輯:黃飛
?
評(píng)論