同一段vec_dot,AVX2 / VNNI / NEON / WASM 四条 SIMD 路径:为什么预填充能拉开 4 倍,解码却几乎一样快?

📅 2026/6/30 3:23:10
同一段vec_dot,AVX2 / VNNI / NEON / WASM 四条 SIMD 路径:为什么预填充能拉开 4 倍,解码却几乎一样快?
把 llama.cpp 编译出 AVX2 和 AVX-512 VNNI 两个版本,拿同一个 7B Q4_0 模型跑llama-bench,你会看到一组分裂的数字:prompt eval(预填充)那一栏,VNNI 比 AVX2 快 43%;token generation(解码)那一栏,两者几乎贴在一起,差不到 5%。同一段热点代码、同一颗 CPU、同一个量化格式,SIMD 指令换了一档,一半场景起飞、另一半场景纹丝不动。这不是测试出错。这是 SIMD 在量化推理里真实的作用边界——它能不能帮到你,取决于你在哪一侧撞墙:算力墙,还是内存带宽墙。一个性能工程师如果在动手之前没把这堵墙认清楚,很容易花一周时间把vec_dot抠快 30%,最后端到端只快了 2%,然后对着 profile 发懵。更有意思的是,这四个平台的实现差异,几乎是一部浓缩的"指令集如何为深度学习让路"的历史。x86 从凑合用多媒体指令maddubs,到专门为神经网络造的 VNNI;ARM 从老核只能vmull硬凑,到 dotprod 一条 SDOT 搞定、再到 i8mm 把矩阵乘塞进单指令;WASM 则卡在最朴素的 128 位基线上,连融合点积都还在提案里。同一个 int8 点积,四个平台用四套指令、四种代价实现,把各家指令集的代际差距摊在了同一段代码上——这本身就是一个绝佳的观察样本。下面我们把这条被调用上亿次的热点路径ggml_vec_dot_q4_0_q8_0,在 x86 AVX2、AVX-512 VNNI、ARM NEON、WebAssembly S