Cortex-A72运行ARMv7 NEON汇编周期高于Cortex-A53的原因求解
Cortex-A53/A72 AArch32模式下NEON代码性能差异原因分析
我在两款运行AArch32模式的ARMv8处理器(Cortex-A53、Cortex-A72)上对一段ARMv7 NEON代码做了基准测试,测试硬件分别为搭载32位Raspbian Buster系统的树莓派3B(Cortex-A53)和树莓派4B(Cortex-A72)。
测试方案
基准测试逻辑
uint32_t x[4]; uint32_t t0 = ccnt_read(); for(int i = 0; i < 1000; i++) armv7_neon(x); uint32_t t1 = ccnt_read(); printf("%u\n",(t1-t0)/1000);
测试用NEON函数实现
.global armv7_neon .func armv7_neon, armv7_neon .type armv7_neon, %function armv7_neon: vld1.32 {q0}, [r0] vmvn.i32 q0, q0 vmov.i32 q8, #0x11111111 vshr.u32 q1, q0, #2 vshr.u32 q2, q0, #3 vmov.i32 q9, #0x20202020 vand q1, q1, q2 vmov.i32 q10, #0x40404040 vand q1, q1, q8 vmov.i32 q11, #0x80808080 veor q0, q0, q1 vmov.i32 q12, #0x02020202 vshl.u32 q1, q0, #5 vshl.u32 q2, q0, #1 vmov.i32 q13, #0x04040404 vand q1, q1, q2 vmov.i32 q14, #0x08080808 vand q3, q1, q9 vshl.u32 q1, q0, #5 vshl.u32 q2, q0, #4 veor q0, q0, q3 vand q1, q1, q2 vmov.i32 q15, #0x32323232 vand q1, q1, q10 vmov.i32 q8, #0x01010101 veor q0, q0, q1 vshl.u32 q1, q0, #2 vshl.u32 q2, q0, #1 vand q1, q1, q2 vand q3, q1, q11 vshr.u32 q1, q0, #2 vshl.u32 q2, q0, #1 veor q0, q0, q3 vand q1, q1, q2 vand q1, q1, q12 veor q0, q0, q1 vshr.u32 q1, q0, #5 vshl.u32 q2, q0, #1 vand q1, q1, q2 vand q3, q1, q13 vshr.u32 q1, q0, #1 vshr.u32 q2, q0, #2 veor q0, q0, q3 vand q1, q1, q2 vand q1, q1, q14 veor q0, q0, q1 vmvn.i32 q0, q0 vand q1, q0, q14 vand q2, q0, q15 vand q3, q0, q8 vand q8, q0, q11 vand q9, q0, q10 vand q10, q0, q13 vshl.u32 q1, q1, #1 vshl.u32 q2, q2, #2 vshl.u32 q3, q3, #5 vshr.u32 q8, q8, #6 vshr.u32 q9, q9, #4 vshr.u32 q10, q10, #2 vorr q0, q1, q2 vorr q1, q3, q8 vorr q2, q9, q10 vorr q3, q0, q1 vorr q0, q3, q2 vst1.32 {q0}, [r0] bx lr .endfunc
编译选项
# Cortex-A53版本编译参数 gcc -O3 -mfpu=neon-fp-armv8 -mcpu=cortex-a53 # Cortex-A72版本编译参数 gcc -O3 -mfpu=neon-fp-armv8 -mcpu=cortex-a72
测试结果
Cortex-A53上单轮执行平均耗时74周期,Cortex-A72上为99周期。已知测试代码不含tbl类指令,排除该指令性能问题影响。
性能差异原因分析
- NEON指令延迟设计差异:Cortex-A53是顺序执行架构,基础NEON逻辑运算(
vand/veor/vshl/vshr等)延迟为1周期,刚好适配你代码中的密集运算场景;Cortex-A72作为乱序架构优先优化通用性能,AArch32模式下上述基础NEON指令延迟提升到2周期,直接拉高了整体耗时。 - 向量立即数移动吞吐量差异:你代码中存在大量
vmov.i32 qN, #立即数指令,Cortex-A53每个周期可发射2条该类指令,而Cortex-A72 AArch32模式下每个周期仅能发射1条,连续的vmov指令直接成为执行瓶颈。 - 长依赖链抵消乱序优势:你的代码是典型的串行依赖结构,所有运算都依赖前一步的寄存器结果,Cortex-A72的乱序调度能力完全无法发挥,反而更高的基础指令延迟被直接放大。
- AArch32兼容模式开销:Cortex-A72的设计优先级偏向AArch64模式,AArch32模式下NEON指令的解码、发射路径存在额外兼容层开销,部分指令调度优先级低于AArch64模式同类指令,进一步降低了执行效率。
- NEON发射端口适配差异:你代码几乎全为同类型NEON运算,刚好适配Cortex-A53的2发射NEON流水线;而Cortex-A72在AArch32模式下的NEON发射端口对连续同类型运算的吞吐量表现弱于A53,没有架构优势。
内容的提问来源于stack exchange,提问作者Raoul722
相关产品推荐
相关产品推荐

