Atri Website

Back

重点#

  • 缓存命中时两种写法:全写、回写的计算
  • 了解未命中时的处理方法

1. 缓存一致性#

因为 cache 中的内容是主存块副本,当对 cache 中的内容进行更新时,就存在 cache 和主存如何保持一致的问题。除此之外,以下情况也会出现 cache 一致性问题:

  1. 多个 I/O 设备访问主存时:如果 CPU 修改了 cache 中的内容,且没有同步到主存,则会造成数据不一致的问题,导致读入 I/O 设备的数据无效
  2. 多核 CPU 共存问题:每个 CPU 都有着自己的 cache,如果多个 cache 里存储着主存里地址相同的数据块,当某个 CPU 修改了 cache 里的内容,主存此时未同步,会导致其他 CPU 里的 cache 存储的数据以及主存存储的数据无效

一致性需要满足两个条件,最关键的操作就是写操作的同步:

  1. 写传播:一个 CPU 对某数据的写操作,最终要能被其他 CPU 看到和知道
  2. 写串行:同一地址的所有写操作,在所有 CPU 看来顺序一致

一般写命中时有两种写方法:全写法、回写法;写缺失时有两种方法:写分配法、非写分配法。

二者搭配使用,例如:全写法 + 非写分配法

2. 写缺失时#

写缺失时有有两种方法:写分配法、非写分配法。

2.1. 写分配法

写分配法(Write-Allocate)的规则是:先更新主存块的目标存储单元,再选择一个 cache 行,把更新后的主存块复制到该 cache 行。即先写主存,再送入 cache。

2.2. 非写分配法

非写分配法(No-Write-Allocate)的规则是:只更新主存单元,不把目标主存块写入 cache。

二者区别很明显:都写入主存块的目标单元,但是否写入 cache?

3. 全写法#

全写法和回写法都是缓存命中是的写规则

规则:写命中时,同时写入主存和缓存。

该方式的做法可保证 cache 和主存始终同步,因此替换 cache 行时,可直接覆盖,不需要担心数据不一致的问题而进行写回(将数据从 cache 写回主存块),通常也被称为通写法或直写法。

但是,这种方法会大大增加写操作的开销(因为主存写速度较慢,会增加 CPU 延时)。例如,假定一次写主存需要 100 个 CPU 时钟周期,那么 10%10\% 的存数指令就使得 CPI 增加了 100×10%=10100×10\%=10 个时钟。

为了减少写主存的开销,通常在 cache 和主存之间加一个写缓冲(write buffer)。在 CPU 写 cache 的同时,也将信息写人写缓冲,然后由存储控制器将写缓冲中的内容写人主存。写缓冲是一个 FIFO 队列,只有少量空间,在写操作频率不是很高的情况下,因为 CPU 只需将信息写快速的写缓冲而无须写慢速的主存,因而效果较好。但是,如果写操作频繁发生,则会使写缓冲饱和而发生阻塞。

4. 回写法#

回写法的规则是:写命中时,只写入缓存。只有该缓存行被替换时,才写回主存。

即:命中 \to 只写入缓存(不写入主存) \to 触发替换算法 \to 缓存写回主存。

由此可见,该方式实际上采用的是回头再写或最后一次性写的做法,因此通常被称为回写法或一次性写方式,也有教材称之为写回法。

在 CPU 执写操作时,回写法不会更新主存单元,只有当 cache 中的主存块被替换时,才将该块内容一次性写回主存。这种方式的好处在于减少了写主存的次数,因而大大降低了主存带宽需求。

为了减少写回主存块的开销,每个 cache 设置了一个修改位(dirty bit,也称“脏位”)

  • 若脏位为 1,则说明对应 cache 中的主存块被修改过,替换时需要写回主存
  • 若脏位为 0,则说明对应主存块未被修改过,替换时无须写回主存

注意到,由于回写法没有同步更新 cache 和主存内容,所以存在 cache 和主存内容不一致而带来的潜在隐患。通常需要其他的同步机制来保证存储信息的一致性。

5. 常用搭配#

回顾四种写规则:

写命中下

  • 全写法:缓存和主存同时写入;由于主存速度较慢,会增大部分时间开销
  • 回写法:只写入缓存;只有该 cache 行被替换时,才从缓存写回主存;由于 cache 和主存不同步,存在不一致性隐患

写缺失下

  • 写分配法(Write-Allocate):先更新目标主存块里的数据单元,再把主存块放入缓存。(先更新,再复制)
  • 非写分配法(No-Write-Allocate):只更新主存块的数据,不写入缓存。(只更新,不复制)

常用的搭配

组合作用
全写法 + 非写分配命中时,同时写入 cache 和主存;缺失时,只写入主存,不放入 cache
回写法 + 写分配命中时,只写入 cache;缺失时,先把主存块送入 cache,再在 cache 里更新

提问:为什么 “回写法 + 写分配” 策略中,缺失时是先把主存块送入 cache 再更新,而不是直接先更新主存块的数据单元,再把主存块送入 cache ?

回复提问:因为回写法的核心思想是:减少主存的写入次数,尽可能提高数据的写入速度(显然 CPU 写入 cache 的速度远比写入主存的速度快)。

因此虽然通用的 “写分配” 策略是先更新主存,再送入 cache,但在实际与回写法组合使用时,应遵循回写法的思想,先把主存块送入 cache,再在 cache 里更新,同时脏位标记为 1,主存块等被替换时再写回主存。这样写缺失时不写入主存,只有替换时才写。

即原文的:“若写缺失,则在 cache 中分配一行,将主存块调入该 cache 行中并更新相应单元的内容。因此,该方式下在写不命中时,通常采用写分配法进行写操作。”

计组:cache 一致性原则
Author Juyao Huang
Published at June 15, 2026
Comment seems to stuck. Try to refresh?✨