缓存友好的数据布局
设计数组结构并打包数据,以提高缓存局部性
缓存友好的数据布局 是 CoddyKit 上的免费 C++ Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 C++ Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 C++ Academy 课程共包含 4 节课。
内存层次结构
CPU 拥有多个缓存级别(L1、L2、L3),其速度远快于主内存。缓存友好的代码会让热点数据靠近 CPU。
缓存行
内存以缓存行为单位读取——通常为 64 字节。读取一个字节会加载整行。请善加利用这一点。
引用局部性
有两个重要属性:
- 空间局部性——很快使用附近的内存
- 时间局部性——很快再次使用同一块内存
连续存储与链式存储
向量会连续存储数据,因此遍历时具有良好的缓存友好性。链表会将内存分散开来,每一步都会破坏缓存。
// Cache friendly
std::vector<int> v(1000);
for (auto& x : v) ++x;
// Cache UNfriendly
std::list<int> l(1000);
for (auto& x : l) ++x;AoS 与 SoA
记录数组有两种布局:
- AoS(结构体数组)——自然直观,但遍历一个字段时会触及所有字段
- SoA(数组结构)——当大多数循环只使用部分字段时更好
// AoS
struct Particle { float x, y, z, vx, vy, vz; };
std::vector<Particle> particles;
// SoA
struct Particles {
std::vector<float> x, y, z, vx, vy, vz;
};结构体打包
按从大到小的顺序排列成员,以尽量减少填充。pahole 等工具可以显示实际布局。
struct Bad { char c; double d; char c2; }; // padded
struct Good { double d; char c; char c2; }; // smaller伪共享
两个线程在同一缓存行上的不同变量中写入数据时,会使彼此的缓存失效。这会严重影响性能。请填充到 64 字节。
struct alignas(64) Counter {
std::atomic<int> value;
};热数据与冷数据分离
将热数据(频繁访问)和冷数据(很少访问)分离到不同的结构中。CPU 只缓存热数据部分。
预分配
使用 reserve 为向量预分配空间,以避免反复重新分配。每次重新分配都会复制所有元素,既昂贵又会严重破坏缓存。
顺序访问更快
对数组进行线性扫描是最快的方式。硬件预取器会自动预测并加载接下来的缓存行。
避免间接访问
指针会迫使 CPU 追踪依赖关系。遍历时,std::vector<T*> 的速度比 std::vector<T> 慢。只有在必要时才使用间接访问。
优化前先分析性能
“缓存友好”是一条指导原则,而不是绝对规则。使用 perf 或 VTune 等工具进行测量,找出缓存未命中造成影响的位置,然后再进行优化。
快速检查
为什么遍历同样大小的 std::vector 通常比遍历 std::list 快得多?
回顾
现代 CPU 依赖缓存。优先使用连续存储的容器,在选择性访问字段时使用 SoA,合理打包结构体,避免伪共享,并使用 perf 或 VTune 分析缓存未命中,以找出热点。
常见问题解答
「缓存友好的数据布局」课时是免费的吗?
是的 — 「缓存友好的数据布局」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 C++ Academy 课程的其余内容,请升级到 CoddyKit PRO。 C++ Academy 课程共包含 4 节课。
「缓存友好的数据布局」这节课中我会学到什么?
设计数组结构并打包数据,以提高缓存局部性 你通过在浏览器中直接运行的动手代码来练习 C++ Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 C++ Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 C++ Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。
「缓存友好的数据布局」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 C++ Academy 课中编写并运行代码吗?
能。每节 C++ Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。