SIMD 优化
问题
Rust 中如何使用 SIMD 加速计算?
答案
SIMD(Single Instruction, Multiple Data)允许一条指令同时处理多个数据。
自动向量化
编译器会自动将简单循环向量化,无需手动写 SIMD:
// 编译器通常能自动向量化这种简单循环
fn sum(data: &[f32]) -> f32 {
data.iter().sum()
}
fn dot_product(a: &[f32], b: &[f32]) -> f32 {
a.iter().zip(b.iter()).map(|(x, y)| x * y).sum()
}
手动 SIMD(std::simd,nightly)
#![feature(portable_simd)]
use std::simd::prelude::*;
fn sum_simd(data: &[f32]) -> f32 {
let (chunks, remainder) = data.as_chunks::<8>();
let mut acc = f32x8::splat(0.0);
for chunk in chunks {
acc += f32x8::from_slice(chunk);
}
acc.reduce_sum() + remainder.iter().sum::<f32>()
}
实战:使用成熟的 SIMD crate
// 大多数场景不需要手写 SIMD,用现成的 crate:
// - simd-json:JSON 解析,比 serde_json 快 2-4x
// - memchr:字节搜索,使用 SIMD 加速
// - regex:内部使用 SIMD 优化匹配
何时使用 SIMD
| 场景 | 建议 |
|---|---|
| 简单数学运算 | 信任编译器自动向量化 |
| JSON 解析 | 用 simd-json |
| 字符串搜索 | 用 memchr |
| 图像处理 | 用 image crate(内部 SIMD) |
| 自定义算法 | std::simd(nightly)或 packed_simd2 |
常见面试问题
Q1: 如何确认代码是否被自动向量化?
答案:
# 查看汇编输出
cargo rustc --release -- --emit asm
# 或使用 Compiler Explorer (godbolt.org) 在线查看
看汇编中是否出现 SIMD 指令(如 vmovaps, vaddps, vmulps)。如果只用标量指令(movss, addss),说明没有向量化。