06. 提高缓存命中率

1.缓存行和局部性原理

2.提高缓存命中率策略


1.缓存行和局部性原理

csharp 复制代码
CPU缓存的最小存储单位是缓存行(Cache Line), 常见大小为64字节; 当CPU从内存读取数据时, 不会只读取目标字节, 而是

会把目标数据所在的整个缓存行(64字节)都加载到缓存中

a.空间局部性: 如果程序接下来要访问的数据和当前数据在内存中是连续的, 那么这些数据已经被加载到缓存里,直接读取即

可(缓存命中)

b.时间局部性: 如果程序在短时间内重复访问同一数据, 该数据会一直留在缓存中, 避免重复从内存读取

这两个局部性原理, 是所有缓存优化策略的基础

2.提高缓存命中率

csharp 复制代码
a.利用空间局部性: 让频繁访问的数据紧凑排列; 核心是"让高频访问的数据在内存中连续存储, 最大化缓存行的利用率"

- 正面例子: 遍历数组

数组是连续内存布局, 遍历数组时, CPU加载一个缓存行就能包含多个数组元素; 比如: 64字节的缓存行, 能装下16个int类

型元素(每个int4 字节); 遍历到第1个元素时, 后续15个元素已经在缓存里了, 命中率接近100%

- 反面例子: 遍历链表

链表的节点是分散内存布局(每个节点的next指针指向随机内存地址), 每次访问下一个节点都要去内存寻址,缓存行只能装一

个节点, 命中率极低

csharp 复制代码
b.利用时间局部性: 让高频数据常驻缓存; 核心是"减少高频数据的缓存驱逐, 让它在缓存里待得更久"

核心手段减少循环内的内存读写, 把循环中需要重复访问的变量, 缓存到局部变量中; 局部变量默认会被分配到CPU的寄存器

或L1缓存中, 访问速度极快

csharp 复制代码
c.避免"伪共享": 别让多线程破坏缓存行

这是多线程编程中容易踩的坑, 也是Unity C#多线程优化的关键

伪共享的本质: 多个线程同时修改同一个缓存行里的不同数据, 会导致缓存行频繁失效(缓存颠簸)

比如两个线程分别修改一个结构体的两个成员, 而这两个成员刚好在同一个缓存行: 线程A修改后, 缓存行标记为脏数据, 线

程B读取时发现缓存行失效, 必须重新从内存加载, 命中率直接归零
csharp 复制代码
现代CPU都是多核的(比如: 4核、8 核), 每个核心都有自己独立的L1、L2缓存, L3缓存是多核共享的; 为了保证所有核心读

取的数据是"一致的"(比如核心 1 修改了某个数据,核心 2 必须看到最新值,不能读旧数据), CPU有一套缓存一致性协议

最常见的是MESI协议, 这个协议有个关键规则: 当某个核心修改了自己缓存中的某个缓存行后, 会立即通知其他所有核心:你

们缓存里的这个缓存行已经失效了, 不能再用了; 其他核心如果后续要访问这个缓存行的数据,必须重新从内存或共享L3缓存

加载最新版本; 这就是伪共享的祸根 ------ 不是数据本身冲突, 而是缓存行被共用, 导致无辜的连带失效
csharp 复制代码
解决方法: 缓存行填充, 通过添加填充字节, 让每个线程操作的数据独占一个缓存行, 避免互相干扰
相关推荐
程序员鱼皮3 天前
刚刚,Claude Opus 4.6 和 GPT-5.3-Codex 同时炸场!AI 编程要变天了
计算机·ai·程序员·互联网·软件开发
白帽子黑客罗哥6 天前
护网行动中遇到突发安全事件的标准应急响应流程
网络·安全·web安全·计算机·护网行动
计算机毕业编程指导师8 天前
大数据可视化毕设:Hadoop+Spark交通分析系统从零到上线 毕业设计 选题推荐 毕设选题 数据分析 机器学习 数据挖掘
大数据·hadoop·python·计算机·spark·毕业设计·城市交通
计算机毕业编程指导师8 天前
【计算机毕设选题】基于Spark的车辆排放分析:2026年热门大数据项目 毕业设计 选题推荐 毕设选题 数据分析 机器学习 数据挖掘
大数据·hadoop·python·计算机·spark·毕业设计·车辆排放
程序员鱼皮9 天前
7个神级技巧,彻底去除网站的 AI 味儿!
计算机·ai·程序员·互联网·网站·编程经验
梁辰兴9 天前
计算机网络基础:停止等待协议
网络·计算机网络·计算机·协议·计算机网络基础·梁辰兴·停止等待协议
番茄灭世神10 天前
Linux从入门到进阶第一章
linux·计算机·操作系统
搞科研的小刘选手11 天前
【虚拟现实/人机交互会议】第二届人工智能、虚拟现实与交互设计国际学术会议(AIVRID)
大数据·人工智能·计算机·aigc·虚拟现实·国际学术会议·交互技术
梁辰兴11 天前
计算机网络基础:传输控制协议 TCP
tcp/ip·计算机网络·计算机·tcp·计算机网络基础·梁辰兴·传输控制协议