Pho*_*non 5 benchmarking assembly arm neon cortex-a8
我正在研究在Android上编写几个实时DSP算法,因此我决定直接在Assembly中编程ARM以尽可能地优化所有内容并使数学最大化.起初我得到的速度基准并没有多大意义,所以我开始阅读有关管道危险,双重问题的能力等等.我仍然对我得到的一些数字感到困惑,所以我将它们发布在这里,希望有人可以解释为什么我得到的东西.特别是,我很感兴趣为什么NEON需要不同的时间来运行不同数据类型的计算,即使它声称在一个周期内完成每个操作.我的发现如下.
我正在使用一个非常简单的循环进行基准测试,我运行它进行了2,000,000次迭代.这是我的功能:
hzrd_test:
@use received argument an number of iterations in a loop
mov r3 , r0
@come up with some simple values
mov r0, #1
mov r1, #2
@Initialize some NEON registers (Q0-Q11)
vmov.32 d0, r0, r1
vmov.32 d1, r0, r1
vmov.32 d2, r0, r1
...
vmov.32 d21, r0, r1
vmov.32 d22, r0, r1
vmov.32 d23, r0, r1
hzrd_loop:
@do some math
vadd.s32 q0, q0, q1
vadd.s32 q1, q0, q1
vadd.s32 q2, q0, q1
vadd.s32 q3, q0, q1
vadd.s32 q4, q0, q1
vadd.s32 q5, q0, q1
vadd.s32 q6, q0, q1
vadd.s32 q7, q0, q1
vadd.s32 q8, q0, q1
vadd.s32 q9, q0,s q1
vadd.s32 q10, q0, q1
vadd.s32 q11, q0, q1
@decrement loop counter, branch to loop again or return
subs r3, r3, #1
bne hzrd_loop
@return
mov r0, r3
mov pc, lr
Run Code Online (Sandbox Code Playgroud)
注意计算操作和数据类型指定为vector add(vadd)和signed 32-bit int(s32).此操作在一定时间内完成(参见下面的结果表).根据这篇ARM Cortex-A8文档和后续页面,NEON中的几乎所有基本算术运算都应该在一个周期内完成,但这就是我所得到的:
vmul.f32 ~62ms vmul.u32 ~125ms vmul.s32 ~125ms vadd.f32 ~63ms vadd.u32 ~29ms vadd.s32 ~30ms
我通过简单地替换上面循环中所有操作和数据类型来完成它们.是否有一个原因vadd.u32是超过两倍快vadd.f32和vmul.f32比快两倍vmul.u32?
干杯! =)
哇,你的结果非常准确:
不错的实验.
也许你已经知道了,但在编写NEON时要小心:
所有这些都将导致巨大的打嗝.
祝好运!
PS:我宁愿优化A9(稍微不同的周期时间),因为几乎所有新设备都带有A9.ARM的A9时序图更具可读性.:-)