在现代 C++ 编程中,cache-friendly(缓存友好) 是一种优化思维方式,旨在最大程度地利用 CPU 的高速缓存(L1/L2/L3 Cache),提高内存访问效率,降低 cache miss 和访问延迟,从而显著提升程序性能。
一、缓存友好编程的核心理念
- CPU cache 是按 cache line(通常是 64 字节)为单位加载数据的。
- 顺序访问内存 会预取下一行,提升命中率。
- 非顺序(跳跃)访问、频繁分配小对象、链式结构 会导致 cache miss。
二、实用的 cache-friendly 编程技巧
1. 结构体/数组数据排列成"结构体数组(SoA)"
不推荐(AoS:Array of Structs):
cpp
struct Particle {
float x, y, z;
float velocity;
};
std::vector<Particle> particles;
- 遍历只
x/y/z会带入很多无用数据(velocity)。 - 空间局部性差。
推荐(SoA:Struct of Arrays):
cpp
struct ParticleSystem {
std::vector<float> x, y, z, velocity;
};
- 顺序访问一个字段变得高效,能充分利用 cache line。
- 有利于 SIMD 向量化优化。
2. 尽量使用连续内存结构(如 std::vector)
相比于:
cpp
std::list<int> list;
更推荐使用:
cpp
std::vector<int> vec;
std::list分配离散内存块,cache 友好性差。std::vector分配一整块内存,访问是顺序且预取友好。
3. 避免频繁分配/释放内存(避免堆分配)
- 分配小对象(如大量
new T)容易污染 cache 和 TLB。 - 尽量使用 内存池(memory pool) 或 对象池(object pool),复用对象。
- 在多线程环境下,可以使用 thread-local allocator 避免 false sharing。
4. 循环优化:使用循环展开 + 预取优化
cpp
for (size_t i = 0; i < N; ++i) {
a[i] += b[i];
}
改进:
- 使用 循环展开(loop unrolling)。
- 手动预取下一块数据(有些编译器会自动做)。
5. 按访问顺序布局结构体字段
cpp
struct Foo {
char a; // 1 byte
double b; // 8 bytes
int c; // 4 bytes
};
改成:
cpp
struct Foo {
double b; // 8 bytes
int c; // 4 bytes
char a; // 1 byte
};
- 避免 padding,节省空间。
- 更重要:连续访问字段时能落在同一个 cache line 内。
6. 防止 false sharing(伪共享)
多个线程访问不同变量时,如果变量落在同一个 cache line,会导致性能急剧下降。
解决方法:
cpp
struct alignas(64) Counter {
int value;
char padding[60]; // 手动填充
};
或使用:
cpp
#include <atomic>
#include <new>
alignas(64) std::atomic<int> counter;
7. 使用 SIMD 和预取指令(高级优化)
如 Intel 的 SSE/AVX、ARM 的 NEON:
cpp
#include <immintrin.h> // AVX
__m256 vecA = _mm256_loadu_ps(&a[i]);
__m256 vecB = _mm256_loadu_ps(&b[i]);
__m256 vecC = _mm256_add_ps(vecA, vecB);
_mm256_storeu_ps(&c[i], vecC);
配合 cache-friendly 数据布局,SIMD 能极大加速批量处理任务。
三、小结:缓存友好技巧汇总
| 技巧 | 描述 |
|---|---|
使用 std::vector 替代链表 |
保证内存连续性 |
| 使用 SoA 替代 AoS | 避免加载无关数据 |
| 结构体字段按访问顺序排列 | 减少 cache miss |
| 避免频繁小对象堆分配 | 使用对象池 |
| 防止 false sharing | 跨线程数据加 padding |
| 合理使用预取和 SIMD | 配合数据布局提升性能 |
: 基础能力系列
: 区块链知识系列
: 密码学系列
: 零知识证明系列
: 共识系列
: 公链调研系列
: BTC系列
: 以太坊系列
: EOS系列
: Filecoin系列
: 联盟链系列
: Fabric系列
: 智能合约系列
: Token系列