|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
+ g5 e% R) F( A通用算术指令:0 l8 J6 r( a' ]/ B. G3 |
* ]6 b% f. d; H: d2 H, E
VABA:绝对值累加、VABD:绝对值相加、VABS:绝对值、VNEG:求反、VADD、VADDW、VADDL、VSUB、VSUBL、VSUBW:加减
0 t+ Z$ u+ U3 S8 ~8 e, |
5 |3 Q& s: ?, X8 S& IVPADD:将两个向量的相邻元素相加0 d' U8 ]+ M1 X! L
' ^. r4 i+ @! C8 ~% P9 m$ R
如VPADD.I16 {d2}, d0, d1
. `' k+ c9 D$ r7 d, E' `! k" o) Q, Y/ z: { p
8 L6 s$ x8 Q5 {3 ?& [4 F
5 N& B, J1 I2 a/ i; mVPADDL:VPADDL.S16 d0, d1
. _9 ]6 Y. P9 W& g* j( j4 G
$ X" L# \' j4 k4 C, `
/ N+ y1 e6 S( {( H/ ?2 s v
$ F8 s( R. r3 v& T2 r9 K! V4 K9 x! MVMAX:最大值,VMIN:最小值
! @) b" e& m9 ~# s" c6 ]$ U H1 A* ~! Z6 M& Q% I
VMUL、VMULL、VMLA(乘加)、VMLS(乘减)、
7 U. E! ~% t* e/ R4 _5 j2 _' i1 m6 D7 C' \ |4 U1 Z
, H& j/ k( a& ~
) H k4 Y$ o9 m7 r
加载存储指令:& d: `1 h. \. M+ { a: W
/ A/ F$ Y u2 i* E/ s" P6 G* \# c* s5 rVLD和VST7 j: u0 i, l1 V% _
) F* X! q1 O9 n5 A- X# W( ]
2 f2 Z4 F" b* W/ G
* A3 W' {$ S" X( f l8 a7 i1 w
' m% E( ]7 ]7 q a1 U* \! c# u5 R% N交叉存取的示意图:0 {3 V" J, b9 c( X1 X& k3 W
, Q5 V4 c- L4 S$ E1 e% M4 y1 T
4 Q9 {/ c5 d# H) R6 r$ p
/ d T' _; B- u+ u- q( k
VREV反转元素指令:# I2 `$ S6 M, k0 }
. s. D* ~' C& o1 O
' h- E/ R0 }5 { h' E+ T$ Z& n( y" ?) ~( T4 a% v
VEXT移位指令:! _; L- G- O( I6 j' U( l
# X5 ^) j7 S* m
* L+ {6 w# z) O9 q% Y9 Z
/ M( `" h; p$ Z1 HVTRN转置指令:可以用于矩阵的转置: G# q$ p8 f" J% W8 q
/ K) ~4 n: ^ T# V
5 u' N' Y8 V7 q3 G% p/ x8 \
; [$ I" w% Z2 F
# u3 v% E% D- @! C" [9 w
7 y, J" ^5 N/ TVZIP指令:压缩,类似交叉存取. z* c1 s0 G! Q" x4 N2 G$ v
) p1 }, \# I( L
K8 M& O( n$ ?0 d+ U0 G1 X+ t5 V% \9 V G' P% j# O/ N) `3 r' j
VUZP指令:解压操作,类似交叉存取. }) t' J& O9 ?- H! j
: j) z' p d2 Q( v1 a! ~$ r
& N+ ~* o( i- V6 Z/ `$ d) j8 p9 A" k7 p0 j: T
VTBL查表指令:从d0,d1中查找d3中的索引值,如果找到则取出,没有找到则为0,存入d2中- Q$ j+ O8 E9 h
/ r2 K R- o) q Q
t) |, f) e1 I* z' b$ s
: o- R2 \4 q3 o5 I8 X( K
! m; i1 e/ l3 C! T. L* y/ q: K三、需要注意的地方
" \% O/ u0 n- h }' v* X& |8 F) R8 I' o$ ]7 z% b' v
load数据的时候,第一次load会把数据放在cache里面,只要不超过cache的大小,下一次load同样数据的时候,则会比第一次load要快很多,会直接从cache中load数据,这样在汇编程序设计的时候是非常需要考虑的问题。
! C g9 N* v$ Y! W! e1 H$ V2 T
$ j3 |* C" M$ y" ]9 D 如:求取一个图像的均值,8*8的窗口,先行求和,然后列求和出来均值,这时候会有两个函数,数据会加载两遍,如果按照这样去优化的话则优化不了多少。如果换成上面这种思路,先做行16行,然后再做列,这样数据都在cache里面,做列的时候load数据会很快。
# C+ j% J) I2 ~: u7 w" W& X) x# C' w+ ^
在做neon乘法指令的时候会有大约2个clock的阻塞时间,如果你要立即使用乘法的结果,则就会阻塞在这里,在写neon指令的时候需要特别注意。乘法的结果不能立即使用,可以将一些其他的操作插入到乘法后面而不会有时间的消耗。
2 @0 C4 m6 v+ D5 x2 r6 c+ A) d7 D6 [ n
如:vmul.u16 q1, d3, d4 ! O2 o- P; _4 u+ C# p
L% M. V: ~' R! ~8 u% U
vadd.u32 q1, q2, q3
' Q& a1 R9 }6 w$ Y# K6 f2 o& u, O }- L3 J1 L+ b/ D6 M
此时直接使用乘法的结果q1则会阻塞,执行vadd需要再等待2个clock的时间% z3 B8 e$ ~8 e
- Y3 M; `7 k0 V
使用饱和指令的时候,如乘法饱和的时候,在做乘法后会再去做一次饱和,所以时间要比直接做乘法要慢。
/ K$ \ W! S& x0 s( e2 d' ?6 }' u i( c$ O6 s; c5 G& u
如: vmul.u16 q1, d3, d4
( v$ R7 B* N9 R/ c- @3 b/ a* j# `
9 f- o1 M$ ]$ x8 s2 z( F& M vqmul.u32 q1, q2, q3
) \1 h% Y4 Q" F& Y7 q" N
: l- X1 }! S# |后一个的时间要比第一个的时间要久。
2 }* m$ S& j6 [7 g1 P% C- e& Y* {# Z5 r6 ^1 B1 K
在对16位数据进行load或者store操作的时候,需要注意的是字节移位。比如是16位数据,则load 8个16位数据,如果指定寄存器进行偏移,此时需要特别注意。
# a' n$ J4 k0 j6 `6 i
9 s7 p/ B: \3 W" \/ z7 e例如:vld1.64 {d0}, [r0], r1
* _9 ]& G, h9 V3 E- D% V A |
|