【arm】arm通用指令及優化技巧


參考:https://blog.csdn.net/billbliss/article/details/78929304

           https://blog.csdn.net/SoaringLee_fighting/article/details/81265865

一、arm通用指令

通用算術指令:

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中

 

二、需要注意的地方

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

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

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

如:vmul.u16 q1, d3, d4 

         vadd.u32 q1, q2, q3

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

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

如:  vmul.u16 q1, d3, d4

          vqmul.u32 q1, q2, q3

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

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

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

5、去除數據之間的依賴

不要將當前指令的目的寄存器作為下一條指令的源寄存器。一般當前指令的運算結果會在下一條指令中使用,我們可以通過指令穿插避免數據依賴。

6、減少分支跳轉

ARM處理器中廣泛使用分支預測技術。但是一旦分支預測失敗,性能就會損失很大。所以, 
盡量不要用分支跳轉!可以采用邏輯運算指令替代分支跳轉! 
比如: 
VCEQ, VCGE, VCGT, VCLE, VCLT…… 
VBIT, VBIF, VBSL…… 
另外,可以使用條件執行指令,比如addgt,suble等減少分支跳轉! 
建議一次性多處理幾行數據,從而減少循環跳轉的次數,提升性能。

 


免責聲明!

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



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