缓存友好与数据局部性
学习目标
- 理解 CPU 缓存层次
- 掌握 AOS vs SOA
- 理解数据局部性
核心概念
缓存行
use std::mem;
const CACHE_LINE_SIZE: usize = 64;
#[repr(align(64))]
struct CacheLine {
data: [u8; 64],
}
AOS vs SOA
struct PointAOS {
x: f64,
y: f64,
z: f64,
}
let points: Vec<PointAOS> = vec![];
struct PointsSOA {
x: Vec<f64>,
y: Vec<f64>,
z: Vec<f64>,
}
实际对比
struct Entity {
position: [f32; 3],
velocity: [f32; 3],
health: f32,
}
struct Entities {
positions: Vec<[f32; 3]>,
velocities: Vec<[f32; 3]>,
health: Vec<f32>,
}
迭代顺序
const N: usize = 1000;
let mut matrix = vec![vec![0.0f64; N]; N];
for i in 0..N {
for j in 0..N {
matrix[i][j] += 1.0;
}
}
for j in 0..N {
for i in 0..N {
matrix[i][j] += 1.0;
}
}
分支预测
let mut data: Vec<i32> = (0..1000).collect();
data.sort();
let sum: i32 = data.iter()
.filter(|&&x| x > 500)
.sum();
小结
| 技巧 | 说明 |
|---|
| SOA | 结构体数组 → 数组结构体 |
| 行优先 | 遍历时内存连续 |
| 缓存行对齐 | #[repr(align(64))] |
| 排序数据 | 提高分支预测准确率 |