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 复制代码
解决方法: 缓存行填充, 通过添加填充字节, 让每个线程操作的数据独占一个缓存行, 避免互相干扰
相关推荐
m0_5474866613 小时前
《计算机控制技术:原理、方法与实现》全套PPT课件
计算机·计算机控制技术
猿的天空4 天前
机器人双手迎来全栈训练系统:灵初智能EgoSteer让灵巧手无所不能
网络·人工智能·计算机·ai·程序员·机器人·编程
m0_547486665 天前
《计算机组成原理教程》全套PPT课件
计算机·计算机组成原理
apcipot_rain11 天前
某双非面试真题
计算机·面试
小小小小钰儿12 天前
网络安全名词术语!
安全·web安全·计算机·网络安全·黑客·编程
猿的天空13 天前
AI视觉原生统一!商汤开源视觉任务大统一模型SenseNova-Vision
人工智能·计算机·ai·程序员·大模型·编程·智能体
猿的天空15 天前
GPT-5.6拆成三段,智能变成了可选购配置
人工智能·gpt·计算机·ai·程序员·大模型·智能体
AI小码18 天前
LLM 应用的缓存工程:当每次 API 调用都在燃烧成本
java·人工智能·spring·计算机·llm·编程·api
zzzll111118 天前
LangChain实战-RAG问答机器人
学习·计算机·程序员·大模型
zzzll111119 天前
Typora插件开发指南:打造专属IDE式写作环境
ide·学习·计算机·大模型·llm·知识