ARM和NEON指令 very nice

在移動平臺上進行一些復雜算法的開發,一般需要用到指令集來進行加速。目前在移動上使用最多的是ARM芯片。

ARM是微處理器行業的一家知名企業,其芯片結構有:armv5、armv6、armv7和armv8系列。芯片類型有:arm7、arm9、arm11、cortex系列。指令集有:armv5、armv6和neon指令。關于ARM到知識參考:http://baike.baidu.com/view/11200.htm

最初的ARM指令集為通用計算型指令集,指令集都是針對單個數據進行計算,沒有并行計算到功能。隨著版本的更新,后面逐漸加入了一些復雜到指令以及并行計算到指令。而NEON指令是專門針對大規模到并行運算而設計的。

NEON 技術可加速多媒體和信號處理算法(如視頻編碼/解碼、2D/3D 圖形、游戲、音頻和語音處理、圖像處理技術、電話和聲音合成),其性能至少為ARMv5 性能的3倍,為?ARMv6 SIMD性能的2倍。

關于SIMD和SISD:Single Instruction Multiple Data,單指令多數據流。反之SISD是單指令單數據。以加法指令為例,單指令單數據(SISD)的CPU對加法指令譯碼后,執行部件先訪問內存,取得第一個操作數;之后再一次訪問內存,取得第二個操作數;隨后才能進行求和運算。而在SIMD型的CPU中,指令譯碼后幾個執行部件同時訪問內存,一次性獲得所有操作數進行運算。這個特點使SIMD特別適合于多媒體應用等數據密集型運算。如下圖所示:

???

如何才能快速到寫出高效的指令代碼?這就需要對各個指令比較熟悉,知道各個指令的使用規范和使用場合。

ARM指令有16個32位通用寄存器,為r0-r15,其中r13為堆棧指針寄存器,r15為指令計算寄存器。實際可以使用的寄存器只有14個。r0-r3一般作為函數參數使用,函數返回值放在r0中。若函數參數超過4個,超過到參數壓入堆棧。

有效立即數的概念:每個立即數采用一個8位的常數(bit[7:0])循環右移偶數位而間接得到,其中循環右移的位數由一個4位二進制(bit[11:8] )的兩倍表示。如果立即數記作<immediate> , 8位常數記作immed_8 , 4位的循環右移值記作rotate_imm ,有效的立即數是由一個8位的立即數循環右移偶數位得到,可以表示成:

<immediate>=immed_8循環右移( 2×rotate_imm)

如:mov r4 , #0x8000 000A??? #0x8000 000A 由0xA8循環右移0x2位得到。

下面介紹一些比較常用到一些指令。


內存訪問指令:

LDR和STR,有三種方式,比較容易搞混

LDR r0, [r1, #4] ??r0 := mem[r1+4]?? ,#4是直接偏移量,這時候只能在正負4Kb到范圍內。也可以是寄存器偏移,用+/-表示。記住r1不進行偏移。

LDR r0, [r1, #4]! ?r0 :=mem[r1+4],r1 := r1 + 4,取值是取偏移量到值,并且r1進行偏移。

LDR r0, [r1], #4 ??r0 :=mem[r1] ,r1 := r1 +4,取值是取r1地方到值,取值后進行偏移。運算后自動加4,后變址。

另外:LDRB是無符號字節,SB是有符號字節,H無符號半字,SH有符號半字。

?

存儲器和寄存器數據交換:SWP,SWPB

如SWP r0, r1, [r2]?? r0 := mem[r2],mem[r2] := r1

多寄存器數據傳輸:

LDMIA r1, {r0,r2,r5}? r0 = mem[r1], r2 = mem[r1+4], r5=mem[r1+8]

?

通用數據處理指令

第二操作數,常用到有LSR,LSL等,如mov r1, r2, lsl #2 將r2左移2位然后賦值到r1中。

常用到操作有ADD、SUB、AND、ORR、EOR、BIC、ORN,如果加上了S則會更新條件標記。

MOV移動,MVN取反移動。MOV可以是R寄存器,立即數以及接第二操作數。

REV:在字或半字內反轉字節或位到順序

MUL、MLA和MLS,乘法、乘加和乘減。MLA R1,R2,R3,R4表示R1=R2*R3+R4,還有有符號和無符號乘法等。

?

跳轉指令

B:無條件跳轉,BL:帶鏈接到跳轉,BX跳轉并交換指令集等。

?

重點介紹一下NEON指令,目前使用較多。而且使用難度也較大,很多文檔上都沒有比較詳細到介紹,也沒有給出相應到例子或者圖示。

?

一、NEON基本知識

NEON的寄存器:

有16個128位四字到寄存器Q0-Q15,32個64位雙子寄存器D0-D31,兩個寄存器是重疊的,在使用到時候需要特別注意,不小心就會覆蓋掉。如下圖所示:

兩個寄存器的關系:Qn =D2n和D2n+1,如Q8是d16和d17的組合。

?

NEON的數據類型:

注意數據類型針對到時操作數,而不是目標數,這點在寫的時候要特別注意,很容易搞錯,尤其是對那些長指令寬指令的時候,因為經常Q和D一起操作。

?

NEON中的正常指令、寬指令、窄指令、飽和指令、長指令

正常指令:生成大小相同且類型通常與操作數向量相同到結果向量

長指令:對雙字向量操作數執行運算,生產四字向量到結果。所生成的元素一般是操作數元素寬度到兩倍,并屬于同一類型。L標記,如VMOVL。

寬指令:一個雙字向量操作數和一個四字向量操作數執行運算,生成四字向量結果。W標記,如VADDW。

窄指令:四字向量操作數執行運算,并生成雙字向量結果,所生成的元素一般是操作數元素寬度的一半。N標記,如VMOVN。

飽和指令:當超過數據類型指定到范圍則自動限制在該范圍內。Q標記,如VQSHRUN

?

二、NEON指令

NEON指令較多,下面主要介紹一些常見的指令用法。

?

復制指令:

VMOV:

兩個arm寄存器和d之間

vmov d0, r0, r1:將r1的內容送到d0到低半部分,r0的內容送到d0到高半部分

vmov r0, r1, d0:將d0的低半部分送到r0,d0的高半部分內容送到r1

一個arm寄存器和d之間

vmov.U32 d0[0], r0:將r0的內容送到d0[0]中,d0[0]指d0到低32位

vmov.U32 r0, d0[0]:將d0[0]的內容送到r0中

立即數:

vmov.U16 d0, #1:將立即數1賦值給d0的每個16位

vmov.U32 q0, #1:將立即數1賦值給q0的每個32位

長指令:VMOVL:d賦值給q

vmovl.U16 q0, d0:將d0的每個16位數據賦值到q0的每個32位數據中

窄指令:VMOVN:q賦值給d

vmovn.I32 d0, q0:將q0的每32位數據賦值到q0的每16位數據中

飽和指令:VQMOVN等,飽和到指定的數據類型

?vqmovun.S32 d0, q0:將q0到每個32位移動到d0中到每個16位中,范圍是0-65535

????????

VDUP:

VDUP.8 d0, r0:將r0復制到d0中,8位

VDUP.16 q0, r0:將r0復制到q0中,16位

VDUP.32 q0, d2[0]:將d2的一半復制到q0中

VDUP.32 d0, d2[1]:將d2的一半復制到d0中

注意是vdup可以將r寄存器中的內容復制到整個neon寄存器中,不能將立即數進行vdup,立即數只能用vmov

?

邏輯運算

VADD:按位與;VBIC:位清除;VEOR:按位異或;VORN:按位或非;VORR:按位或

?

移位指令:

VSHL:左移、VSHLL:左移擴展、VQSHL:左移飽和、VQSHLU:無符號左移飽和擴展

VSHR:右移、VSHRN:右移窄、VRSHR:右移舍入、VQSHRUN:無符號右移飽和舍入

?

通用算術指令:

VABA:絕對值累加、VABD:絕對值相加、VABS:絕對值、VNEG:求反、VADD、VADDW、VADDL、VSUB、VSUBL、VSUBW:加減

VPADD:將兩個向量的相鄰元素相加

如VPADD.I16 {d2}, d0, d1


VPADDL:VPADDL.S16 d0, d1


VMAX:最大值,VMIN:最小值

VMUL、VMULL、VMLA(乘加)、VMLS(乘減)、

?

加載存儲指令:

VLD和VST



交叉存取的示意圖:

VREV反轉元素指令:

?

VEXT移位指令:

?

VTRN轉置指令:可以用于矩陣的轉置



VZIP指令:壓縮,類似交叉存取

VUZP指令:解壓操作,類似交叉存取


?

VTBL查表指令:從d0,d1中查找d3中的索引值,如果找到則取出,沒有找到則為0,存入d2中

?

三、需要注意的地方

??? load數據的時候,第一次load會把數據放在cache里面,只要不超過cache的大小,下一次load同樣數據的時候,則會比第一次load要快很多,會直接從cache中load數據,這樣在匯編程序設計的時候是非常需要考慮的問題。

???? 如:求取一個圖像的均值,8*8的窗口,先行求和,然后列求和出來均值,這時候會有兩個函數,數據會加載兩遍,如果按照這樣去優化的話則優化不了多少。如果換成上面這種思路,先做行16行,然后再做列,這樣數據都在cache里面,做列的時候load數據會很快。

?? 在做neon乘法指令的時候會有大約2個clock的阻塞時間,如果你要立即使用乘法的結果,則就會阻塞在這里,在寫neon指令的時候需要特別注意。乘法的結果不能立即使用,可以將一些其他的操作插入到乘法后面而不會有時間的消耗。

如:vmul.u16 q1, d3, d4?

? ? ? ? ?vadd.u32 q1, q2, q3

此時直接使用乘法的結果q1則會阻塞,執行vadd需要再等待2個clock的時間

使用飽和指令的時候,如乘法飽和的時候,在做乘法后會再去做一次飽和,所以時間要比直接做乘法要慢。

如:? vmul.u16 q1, d3, d4

? ? ? ? ? vqmul.u32 q1, q2, q3

后一個的時間要比第一個的時間要久。

在對16位數據進行load或者store操作的時候,需要注意的是字節移位。比如是16位數據,則load 8個16位數據,如果指定寄存器進行偏移,此時需要特別注意。

例如:vld1.64 {d0}, [r0], r1

?

參考資料:

http://blogs.arm.com/software-enablement/277-coding-for-neon-part-4-shifting-left-and-right/

http://blogs.arm.com/software-enablement/161-coding-for-neon-part-1-load-and-stores/

http://blogs.arm.com/software-enablement/684-coding-for-neon-part-5-rearranging-vectors/


轉自:http://blog.csdn.net/chshplp_liaoping/article/details/12752749

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/447260.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/447260.shtml
英文地址,請注明出處:http://en.pswp.cn/news/447260.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

IPFS下載安裝和配置

參考鏈接 因為這個網站訪問速度很慢&#xff0c;我提供了IPFS的MAC版本。有需要的查看我的資源下載。 大致流程 安裝 $ ls go-ipfs_v0.4.10_darwin-amd64.tar.gz $ tar xvfz go-ipfs_v0.4.10_darwin-amd64.tar.gz x go-ipfs/build-log x go-ipfs/install.sh x go-ipfs/ipfs…

IPFS的相關操作命令

新增文件 在桌面新建名字為1121的文件夾&#xff0c;在文件夾里面新建file.txt文件&#xff0c;在文件里面輸入數據&#xff0c;保存退出 $ pwd /Users/CHY/Desktop $ mkdir 1121 $ cd 1121/ $ vi file.txt $ cat file.txt 哈哈&#xff0c;為什么只有我不快樂 給文件輸入內容…

Neon Intrinsics各函數介紹

#ifndef __ARM_NEON__ #error You must enable NEON instructions (e.g. -mfloat-abisoftfp -mfpuneon) to use arm_neon.h #endif/*(1)、正常指令&#xff1a;生成大小相同且類型通常與操作數向量相同的結果向量&#xff1b; (2)、長指令&#xff1a;對雙字向量操作數執行運算…

npm安裝包總是失敗了的,請參考

鏡像使用方法 &#xff08;三種辦法任意一種都能解決問題&#xff0c;建議使用第三種&#xff0c;將配置寫死&#xff0c;下次用的時候配置還在&#xff09;: 1.通過config命令 npm config set registry https://registry.npm.taobao.org npm info underscore //&#xff08…

arm 開發工具比較(ADS vs RealviewMDK vs RVDS)

ADS REALVIEW MDK RVDS 公司 ARM Keil&#xff08;后被ARM收購&#xff09; ARM 版本 最新1.2 ,被RVDS取代 最新4.0 是否免費 破解情況 有 有 工程管理 CodeWarrior IDE nVision IDE Eclipse/ CodeWarrior IDE 編譯器 ARM C compiler for AD…

解決macOS Catalina(10.15)解決阻止程序運行“macOS無法驗證此App不包含惡意軟件”

在終端里面輸入如下命令 sudo spctl --master-disable 下面圖片對比執行命令前后&#xff0c;安全性與隱私 界面上顯示的差異&#xff1a;使用命令之后&#xff0c;界面變了

MSYS2 + MinGW-w64 + Git + gVim 環境配置

原文 http://dantvt.is-programmer.com/posts/63161.html 以前用 MSYS 的多&#xff0c;最近重裝系統順帶把環境重新配一下&#xff0c;發現 MSYS2 挺順手的。 一、安裝 MSYS2 先裝 MSYS2 的好處是之后可以將 $HOME 設為 /home/name/&#xff0c;再裝其他 *nix 系工具時配置…

MAC版 的最新Docker 2.2版本配置國內代理的解決辦法

點擊Docker圖標&#xff0c;選擇Preference選項&#xff0c;進行國內代理的問題 輸入內容如下 {"experimental": false,"debug": true,"registry-mirrors": ["https://docker.mirrors.ustc.edu.cn", "https://hub-mirror.c.163.…

常用的Homebrew的命令的使用

&#xff08;1&#xff09;安裝軟件&#xff1a;brew install 軟件名&#xff0c;例如&#xff1a;brew install wget &#xff08;2&#xff09;搜索軟件&#xff1a;brew search 軟件名 &#xff08;3&#xff09;卸載軟件&#xff1a;brew uninstall 軟件名 &#xff08;…

微軟正式提供Visual Studio 2013正式版下載(附直接鏈接匯總)

轉自 http://www.iruanmi.com/visual-studio-2013/ 微軟已經向MSDN訂閱用戶提供了Visual Studio 2013正式版鏡像下載&#xff0c;不過非MSDN用戶可以在微軟的Visual Studio 2013官方網站上下載到正式版鏡像&#xff08;通過下載專業版本&#xff0c;已驗證與MSDN版本一致&…

《算法的樂趣》作者王曉華訪談:多看、多做、多想是秘訣

摘要&#xff1a;王曉華是一位熱衷于算法研究的程序員&#xff0c;他是CSDN算法專欄的超人氣博主&#xff0c;也是《算法的樂趣》一書的作者。近日&#xff0c;筆者采訪了王曉華&#xff0c;請他分享算法的經驗之道。 王曉華是一位熱衷于算法研究的程序員&#xff0c;他是CSDN…

基于Mac環境搭建以太坊私有區塊鏈進行挖礦模擬

第一步&#xff1a;相關軟件的安裝 go-ethereum客戶端安裝Go-ethereum客戶端通常被稱為Geth&#xff0c;它是個命令行界面&#xff0c;執行在Go上實現的完整以太坊節點。Geth得益于Go語言的多平臺特性&#xff0c;支持在多個平臺上使用(比如Windows、Linux、Mac)。Geth是以太坊…

Springboot 添加server.servlet.context-path

Springboot 2.0變革后的配置區別 1、springboot 2.0之前&#xff0c;配置為 server.context-path 2、springboot 2.0之后&#xff0c;配置為 server.servlet.context-path

vs2015 支持Android arm neon Introducing Visual Studio’s Emulator for Android

visual studio 2015支持Android開發了。 Microsoft released Visual Studio 2015 Preview this week and with it you now have options for Android development. When choosing one of those Android development options, Visual Studio will also install the brand new Vi…

基于linux環境采用update-alternatives 方式進行python版本切換

采用update-alternatives 切換版本 update-alternatives是Debian提供的一個工具&#xff0c;通過鏈接的方式&#xff0c;但是其切換的過程非常方便。首先看一下update-alternatives的幫助信息&#xff1a; $ update-alternatives --help 用法&#xff1a;update-alternatives …

FFmpeg示例程序合集-批量編譯腳本

此前做了一系列有關FFmpeg的示例程序&#xff0c;組成了《 最簡單的FFmpeg示例程序合集》&#xff0c;其中包含了如下項目&#xff1a;simplest ffmpeg player: 最簡單的基于FFmpeg的視頻播放器simplest ffmpeg audio player: 最簡單的基于FFmpeg的音頻…

基于Ubuntu環境使用docker搭建對于中文識別的chineseocr_lite項目

光學字符識別&#xff08;OCR&#xff09; 光學字符識別&#xff08;OCR&#xff09;目前已經有了很廣泛的應用&#xff0c;很多開源項目都會嵌入OCR 來擴展原有的能力&#xff0c;例如身份證識別、出入停車場的車牌識別、拍照翻譯等等本文介紹的開源的中文 OCR 項目&#xff…

Ubuntu環境使用conda安裝輕量級中文ocr開源項目chineseocr_lite,最簡單的方式

問題 接使用docker的方式來創建項目所報的錯誤選中文件之后&#xff0c;界面不停的繞圈&#xff0c;顯示不了對于圖片的識別結果&#xff0c;并且監控界面上出現錯誤提示如下ImportError: libpython3.6m.so.1.0: cannot open shared object file: No such file or directory&a…

基于Ubuntu使用docker的方式來搭建基于Yolo3+crnn的Chineseocr識別

Docker Docker簡單易用&#xff0c;具體的安裝和配置可以看我的或者其他人的博客 安裝完之后&#xff0c;輸入以下命令安裝chineseocr并且開啟服務 docker pull zergmk2/chineseocr docker run -d -p 8080:8080 zergmk2/chineseocr 在瀏覽器輸入http://127.0.0.1:8080/ocr網…

c/c++ 內存使用指南 和實踐指導

如果你完全理解如下內容&#xff0c; 請聯系我&#xff1a;szu030606163.com&#xff0c; 討論更深層次合作 。 1. 大內高手—內存模型 單線程模型 多線程模型 2. 大內高手—棧/堆 backtrace的實現 alloca的實現 可變參數的實現。 malloc/free系列函數簡介 new…