写缓存的时候,数据是立刻同步到内存,还是先攒着?这就是直写(Write-Through)和写回(Write-Back)的区别。两种策略没有绝对好坏,一致性和性能坐在跷跷板两头。
两种策略的核心差异
| 维度 | 直写(Write-Through) | 写回(Write-Back) |
|---|---|---|
| 写操作 | 同时写缓存和主存 | 只写缓存,标记为"脏" |
| 一致性 | 缓存和内存实时一致 | 内存可能滞后,替换时才回写 |
| 写速度 | 慢(每次都要访存) | 快(只写缓存) |
| 带宽占用 | 高 | 低(合并写入) |
| 实现复杂度 | 简单 | 复杂(需要脏位管理) |
| 崩溃风险 | 低,数据都在内存 | 高,脏数据可能丢失 |
直写:保险但慢
原理:写缓存的时候,顺手把内存也更新了。两边数据永远一致。
优点:简单省心,内存里永远是最新数据,崩溃也不怕。
缺点:每次写都要访存,慢。如果程序频繁写同一个变量,内存总线要被刷爆了。
适合场景:金融交易、数据库日志、多核缓存一致性要求高的地方。
写回:快但有风险
原理:写操作只动缓存,被修改的缓存行打个"脏"标记。等到这行要被踢出去的时候,再一次性写回内存。
优点:写操作飞快,多次修改可以合并成一次内存写入,省带宽。
缺点:实现复杂,需要脏位、替换策略。如果这时候断电,脏数据就没了。
适合场景:图形渲染、科学计算、GPU缓存、普通CPU的L2/L3缓存。
一个具体例子
假设有个变量 a 在内存地址 0x1000,当前值是10。CPU执行 a = 20。

示例流程图
常见组合:
- 写直达 + 非写分配(简单场景)
- 写回 + 写分配(高性能场景)
实际系统中的选择
| 缓存层级 | 典型策略 | 原因 |
|---|---|---|
| L1指令缓存 | 只读,不涉及 | 指令一般不修改 |
| L1数据缓存 | 写回为主 | 速度优先,硬件保证一致性 |
| L2/L3缓存 | 写回为主 | 减少内存流量 |
| 多核共享缓存 | 写回 + MESI协议 | 平衡性能和一致性 |
| 数据库日志 | 直写 | 不能丢数据 |
Intel的CPU从L1到L3基本都是写回,通过MESI协议保证多核一致性。只有在一些嵌入式系统或者特殊场景,才会用直写。
一句话总结
直写是实时同步,保险但慢;写回是延迟批量,快但有丢数据风险。现代CPU为了性能,基本都是写回,靠硬件协议保证不出乱子。