数据级并行是 ARM 性能的重要来源。这一篇聚焦「SIMD / NEON 向量化」维度,用 NEON 内建函数把一个标量循环向量化,并和编译器自动向量化做个对照。
说明:代码为节选,聚焦「优化前 vs 优化后」的关键差异;完整可编译运行的用例见 arm-perf/cases/ 目录。
01 · ARM NEON SIMD 向量化
把 uint32 数组逐元素相加的标量循环向量化。
❌ 原始代码(性能问题所在)
/* baseline:标量逐元素相加 */
uint64_t t0 = now_ns();
for (uint32_t i = 0; i < N; i++) c[i] = a[i] + b[i];
uint64_t t1 = now_ns();
sink_u32(c[N - 1]);
uint64_t base = t1 - t0;
🔍 慢在哪
标量循环一次只算一个元素,没有利用 CPU 的数据级并行能力。
✅ 优化后的代码
/* optimized:NEON 一次处理 4 个元素 */
t0 = now_ns();
uint32_t i = 0;
for (; i + 3 < N; i += 4) {
uint32x4_t va = vld1q_u32(&a[i]);
uint32x4_t vb = vld1q_u32(&b[i]);
uint32x4_t vc = vaddq_u32(va, vb);
vst1q_u32(&c[i], vc);
}
for (; i < N; i++) c[i] = a[i] + b[i];
t1 = now_ns();
sink_u32(c[N - 1]);
uint64_t opt = t1 - t0;
print_result("neon_simd", base, opt);
return 0;
}
#else
#include <stdio.h>
int main(void) {
printf("SKIP neon_simd (requires aarch64)n");
return 0;
}
#endif
🛠 怎么优化
用 NEON 的 128-bit 向量指令(vld1q/vaddq/vst1q)一次加载、运算、写回 4 个 uint32。
📊 实测结果
ARM(aarch64, QEMU):基线 4,248,552 ns → 优化 2,887,390 ns,加速 1.471×。
📱 ARM 视角
NEON 是 ARM 的 SIMD 扩展,图像/音频/加解密等批量运算的提速利器;编译器自动向量化搞不定时,就上手写 intrinsics。
本系列其余文章见「性能优化」分类,或回到《传统ARM优化的思考》看总述。
