跳到主要内容

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),说明没有向量化。

相关链接