<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > ARM平臺(tái)NEON指令的編譯和優(yōu)化

          ARM平臺(tái)NEON指令的編譯和優(yōu)化

          作者: 時(shí)間:2016-11-10 來(lái)源:網(wǎng)絡(luò) 收藏
          本文介紹了ARM平臺(tái)基于ARM v7-A架構(gòu)的ARM Cortex-A系列處理器(Cortex-A5, Cortex-A7, Cortex-A8, Cortex-A9, Cortex-A15)上的NEON多媒體處理硬件加速器針對(duì)C/C++語(yǔ)言、匯編語(yǔ)言和NEON intrinsics如何編譯和優(yōu)化,包含如何向量化、向量化的ARMCC和GCC編譯器選項(xiàng)、NEON的匯編和EABI程序調(diào)用規(guī)范、如何在bare-metal和Linux操作系統(tǒng)上檢測(cè)NEON硬件、如何指導(dǎo)編譯器進(jìn)行向量化NEON指令的優(yōu)化等內(nèi)容。

          NEON向量化

          基于ARM v7-A架構(gòu)的ARM Cortex-A系列處理器(Cortex-A5, Cortex-A7, Cortex-A8, Cortex-A9, Cortex-A15)都可以選用NEON多媒體處理器加速程序運(yùn)行,NEON是一種SIMD(Single Instruction Multiple Data)架構(gòu)的協(xié)處理器,ARM的NEON處理器還可選配置成向量浮點(diǎn)VFPv3(Vector Floating-Point)指令集處理器。

          本文引用地址:http://www.ex-cimer.com/article/201611/317417.htm

          常用的編譯器選項(xiàng)配置

          自動(dòng)向量化選項(xiàng)

          armcc編譯器使用--vectorize選項(xiàng)來(lái)使能向量化編譯,一般選擇更高的優(yōu)化等級(jí)如-O2或者-O3就能使能--vectorize選項(xiàng)。

          gcc編譯器的向量化選項(xiàng)-ftree-vectorize來(lái)使能向量化選項(xiàng),使用-O3會(huì)自動(dòng)使能-ftree-vectorize選項(xiàng)。

          選擇處理器類(lèi)型

          armcc編譯器使--cpu 7-A或者--cpu Cortex-A8來(lái)指定指令集架構(gòu)和CPU類(lèi)型。

          gcc編譯器的處理器選項(xiàng)-mfpu=neon和-mcpu來(lái)指定cpu類(lèi)型。如-mcpu=cortex-a5

          選擇NEON和VFP類(lèi)型

          gcc選擇用-mfpu=vfpv3-fp16來(lái)指定為vfp協(xié)處理,而-mfpu=neon-vfpv4等就能指定為NEON+VFP結(jié)構(gòu)。

          選擇浮點(diǎn)處理器和ABI接口類(lèi)型

          -mfloat-abi=soft使用軟件浮點(diǎn)庫(kù),不是用VFP或者NEON指令;-mfloat-abi=softfp使用軟件浮點(diǎn)的調(diào)用規(guī)則,而可以使用VFP和NEON指令,編譯的目標(biāo)代碼和軟件浮點(diǎn)庫(kù)鏈接使用;

          -mfloat-abi=hard使用VFP和NEON指令,并且改變ABI調(diào)用規(guī)則來(lái)產(chǎn)生更有效率的代碼,如用vfp寄存器來(lái)進(jìn)行浮點(diǎn)數(shù)據(jù)的參數(shù)傳遞,從而減少NEON寄存器和ARM寄存器的拷貝。

          常用的CPU類(lèi)型編譯器選項(xiàng)

          CPU類(lèi)型

          CPU類(lèi)型選項(xiàng)

          FP選項(xiàng)

          FP + SIMD選項(xiàng)

          備注

          Cortex-A5

          -mcpu=cortex-a5

          -mfpu=vfpv3-fp16

          -mfpu=vfpv3-d16-fp16

          -mfpu=neon-fp16

          -d16表明只有前16個(gè)浮點(diǎn)寄存器可用

          Cortex-A7

          -mcpu=cortex-a7

          -mfpu=vfpv4

          -mfpu=vfpv4-d16

          -mfpu=neon-vfpv4

          -fp16表明支持16bit半精度浮點(diǎn)操作

          Cortex-A8

          -mcpu=cortex-a8

          -mfpu=vfpv3

          -mfpu=neon

          Cortex-A9

          -mcpu=cortex-a9

          -mfpu=vfpv3-fp16

          -mfpu=vfpv3-d16-fp16

          -mfpu=neon-fp16

          Cortex-A15

          -mcpu=cortex-a15

          -mfpu=vfpv4

          -mfpu=neon-vfpv4

          常用的gcc組合編譯器選項(xiàng)

          Cortex-A15 with a NEON unit

          arm-gcc -O3 -mcpu=cortex-a15 -mfpu=neon-vfpv4 -mfloat-abi=hard -ffast-math -omyprog.exe myprog.c

          Cortex-A9 with a NEON unit

          arm-gcc -O3 -mcpu=cortex-a9 -mfpu=neon-vfpv3-fp16 -mfloat-abi=hard -ffast-math -omyprog.exe myprog.c

          Cortex-A7 without a NEON unit

          arm-gcc -O3 -mcpu=cortex-a7 -mfpu=vfpv4-d16 -mfloat-abi=softfp -ffast-math -omyprog2.exe myprog2.c

          Cortex-A8 without a NEON unit

          arm-gcc -O3 -mcpu=cortex-a8 -mfloat-abi=soft -c -o myfile.o myfile.c

          NEON匯編和EABI程序調(diào)用規(guī)范

          GNU assembler (gas) and ARM Compiler toolchain assembler (armasm)都支持NEON指令的匯編。但必須遵循ARM Embedded Application Binary Interface (EABI)EABI的規(guī)范,即NEON寄存器的S0-S15 (D0-D7, Q0-Q3)用于傳遞參數(shù)和返回值,被調(diào)用函數(shù)內(nèi)可以直接使用,不用保存;D16-D31 (Q8-Q15)則有調(diào)用函數(shù)來(lái)保存,被調(diào)用函數(shù)內(nèi)可以不保存的隨意使用;而S16-S31 (D8-D15, Q4-Q7)則必須由被調(diào)用函數(shù)內(nèi)部保存。對(duì)于調(diào)用傳參規(guī)范則有,對(duì)于軟件浮點(diǎn),參數(shù)有R0~R3和堆棧stack傳遞,而硬件浮點(diǎn),可以通過(guò)NEON寄存器來(lái)傳遞參數(shù)。

          NEON硬件檢測(cè)和使能

          編譯時(shí)指定NEON單元是否存在

          ARM編譯器(armcc)從4.0之后就支持在某些處理器和FPU的選項(xiàng)中預(yù)定義宏__ARM_NEON__, armasm的宏TARGET_FEATURE_NEON.

          運(yùn)行時(shí)指定檢測(cè)NEON單元

          OS內(nèi)可以檢測(cè)NEON單元是否存在,如Linux下cat /proc/cpuinfo看是否包含NEON或者VFP,如Tegra2 (雙核 Cortex-A9 帶 FPU), cat /proc/cpuinfo:

          Features : swp half thumb fastmult vfp edsp thumbee vfpv3 vfpv3d16

          四核 Cortex-A9 帶NEON單元

          Features : swp half thumb fastmult vfp edsp thumbee neon vfpv3

          另外可以查看/proc/self/auxv,這里會(huì)包含二進(jìn)制格式的hwcap,可以通過(guò)AT_HWCAP來(lái)搜索到。HWCAP_NEON bit (4096).另外如Ubuntu的發(fā)布在路徑/lib/neon/vfp下包含lib的NEON優(yōu)化版本。

          Bare-metal模式下使能NEON

          #include

          // Bare-minimum start-up code to run NEON code

          __asm void EnableNEON(void)

          {

          MRC p15,0,r0,c1,c0,2 // Read CP Access register

          ORR r0,r0,#0x00f00000 // Enable full access to NEON/VFP by enabling access to

          // Coprocessors 10 and 11

          MCR p15,0,r0,c1,c0,2 // Write CP Access register

          ISB

          MOV r0,#0x40000000 // Switch on the VFP and NEON hardware

          MSR FPEXC,r0 // Set EN bit in FPEXC

          }

          下面的EnableNEON函數(shù)使能NEON協(xié)處理器;使用下面的編譯選擇就能在bare-metal下使能NEON

          armcc -c --cpu=Cortex-A8 --debug hello.c -o hello.o

          armlink --entry=EnableNEON hello.o -o hello.axf

          系統(tǒng)運(yùn)行時(shí)使能NEON

          內(nèi)核在遇到第一個(gè)NEON指令時(shí)會(huì)產(chǎn)生一個(gè)Undefined Instruction的異常,這會(huì)讓內(nèi)核自動(dòng)重啟NEON協(xié)處理器,內(nèi)核還可以在上下文切換時(shí)關(guān)閉NEON來(lái)省電。

          Linux內(nèi)核的NEON配置

          圖1. NEON的Linux內(nèi)核配置

          使能NEON,需要選擇

          Floating point emulation→VFP-format floating point maths

          和Floating point emulation→Advanced SIMD (NEON) Extension

          檢查L(zhǎng)inux的配置文件來(lái)確認(rèn)內(nèi)核是否使能NEON

          zcat /proc/config.gz | grep NEON

          看是否存在

          CONFIG_NEON=y

          確認(rèn)處理器是否支持NEON

          cat /proc/cpuinfo | grep neon

          看是否有如下內(nèi)容

          Features : swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt

          向量化NEON優(yōu)化指南

          避免指針混疊alias

          C90不要求指針位置,不同指針可以指向相同的內(nèi)存區(qū)域,C99中引入了__restrict關(guān)鍵字來(lái)表明只有這個(gè)指針能指向它工作的區(qū)域。

          告訴編譯器循環(huán)信息

          如循環(huán)是否某個(gè)整數(shù)的整數(shù)倍,以方便向量化;如下表明循環(huán)次數(shù)是4的整數(shù)倍:

          for(i=0 ; i < (len & ~3) ; i++)

          {

          。。。

          }

          for (i=0; i<(items*4); i+=1)

          {

          。。。

          }

          循環(huán)展開(kāi)

          #pragma unroll (n)

          采用NEON Intrinsics

          armcc, GCC/g++和llvm等編譯器都支持 NEON C/C++ intrinsics,并且采用相同的語(yǔ)法規(guī)范。因而代碼可以在各個(gè)編譯器間共享。NEON Intrinsics的代碼容易維護(hù)而且效率高。NEON Intrinsics采用新的數(shù)據(jù)類(lèi)型,這些類(lèi)型對(duì)應(yīng)于D和Q寄存器。NEON Intrinsics寫(xiě)起來(lái)像是函數(shù)調(diào)用但對(duì)應(yīng)于每一條NEON指令。編程N(yùn)EON Intrinsics時(shí)不用考慮具體的寄存器分配和代碼的schedule,pipeline流水安排等。但NEON Intrinsics往往不能產(chǎn)生想象的代碼,性能上相比純匯編要稍差一些。

          減少循環(huán)內(nèi)的相關(guān)性

          如果當(dāng)前迭代時(shí)使用的數(shù)據(jù)是上次迭代計(jì)算的結(jié)果,就產(chǎn)生了迭代間的相關(guān)性,可以拆分循環(huán)來(lái)減少相關(guān)。

          向量化其他準(zhǔn)則

          • 短小的循環(huán)更容易讓編譯器實(shí)現(xiàn)自動(dòng)向量化;
          • 避免在循環(huán)內(nèi)使用break退出循環(huán)
          • 避免在循環(huán)內(nèi)使用過(guò)多的條件語(yǔ)句,減少可能產(chǎn)生的條件跳轉(zhuǎn);
          • 讓循環(huán)次數(shù)盡可能是2的冪次
          • 讓編譯器知曉循環(huán)次數(shù),減少對(duì)循環(huán)次數(shù)為0等的判斷;
          • 循環(huán)內(nèi)調(diào)用的函數(shù)盡量inline內(nèi)聯(lián)
          • 使用數(shù)組+索引的方式訪(fǎng)問(wèn)比指針形式更容易向量化;
          • 間接尋址(多重索引)不會(huì)向量化;
          • 使用restrict關(guān)鍵字來(lái)告訴編譯器沒(méi)有重疊的內(nèi)存區(qū)域;

          總結(jié)

          本文介紹了ARM平臺(tái)基于ARM v7-A架構(gòu)的ARM Cortex-A系列處理器(Cortex-A5, Cortex-A7, Cortex-A8, Cortex-A9, Cortex-A15)上的NEON多媒體處理硬件加速器針對(duì)C/C++語(yǔ)言、匯編語(yǔ)言和NEON intrinsics如何編譯和優(yōu)化,包含如何向量化、向量化的ARMCC和GCC編譯器選項(xiàng)、NEON的匯編和EABI程序調(diào)用規(guī)范、如何在bare-metal和Linux操作系統(tǒng)上檢測(cè)NEON硬件、如何指導(dǎo)編譯器進(jìn)行向量化NEON指令的優(yōu)化等內(nèi)容。

          參考

          http://houh-1984.blog.163.com/

          本文介紹了ARM平臺(tái)基于ARM v7-A架構(gòu)的ARM Cortex-A系列處理器(Cortex-A5, Cortex-A7, Cortex-A8, Cortex-A9, Cortex-A15)上的NEON多媒體處理硬件加速器針對(duì)C/C++語(yǔ)言、匯編語(yǔ)言和NEON intrinsics如何編譯和優(yōu)化,包含如何向量化、向量化的ARMCC和GCC編譯器選項(xiàng)、NEON的匯編和EABI程序調(diào)用規(guī)范、如何在bare-metal和Linux操作系統(tǒng)上檢測(cè)NEON硬件、如何指導(dǎo)編譯器進(jìn)行向量化NEON指令的優(yōu)化等內(nèi)容。



          評(píng)論


          技術(shù)專(zhuān)區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();