Post

cache之读写一致性

cache之读写一致性

cache之读写一致性

cache根据写操作后是否要直接同步到内存,可分为write back(稍后同步)和write through(立刻同步)。write through的方式虽然享受不到写cache带来的性能优势,但是还是可以享受读cache的好处的,而且其(和内存的)一致性维护也更简单,适用场景包括视频输出等。

write back可以减少不必要的内存写入,减轻总线竞争。现在大部分应用场景下,cache多采用write back的方式,本文以下的讨论都基于write back且只有一个levelcache

🌲 cache一致性(coherency

cache为维护一致性的操作可分为flushinvalidate

CPU更改了某条cache line中的数据,则该cache line中的数据比对应内存中的数据新,此时需要将这条cache line标记为modified,以便在必要时候(cache满了,该cache line需要被释放,把位子腾出来给新的cache line)将cache line中的内容flush到内存来同步。

在使用DMA的时候,外设(比如网卡)过来的数据会不经过CPU直接传送到内存,这时内存中的数据就比对应cache中的数据要新,需要使无效(invalidate)相关的cache line(标记为dirty),这样CPU下次读取这条cache line里的数据的时候,才能知道这些数据不是最新的,得从内存更新。其实某条cache lineinvalidate之后就没有利用价值了,等同于不存在,相当于被清空了,所以也可以算是一种flush

🍃 cache读写

首先,需要系统的cacheenable的状态(在x86中由CR0寄存器的CD位控制),并且要读写的地址所在内存区域的属性是cachable的,CPU才会首先尝试去cache中读写。

d-cachedata cache)和i-cacheinstruction cache)都是可读的,读操作可分为三种情况:

  1. 地址对应的cache line不存在,也就是cache miss,需要从外部内存读取,然后填充到对应cache line(这一过程被称为cache line fill)。
  2. 地址对应的cache line存在但被标记位了invalidate,处理方法同1是一样的。
  3. 地址对应的cache line存在,也就是cache hitread hit),这种情况最简单了,直接读cache line就可以。

i-cache是只读的,只有d-cache是可写的(这也是为什么cache要划分成i-cached-cache的原因),写操作也可分为三种情况::

  1. 地址对应的cache line不存在,可以和读操作一样采用cache line fill(这一过程被称为write allocate),再改写该cache line的内容,然后标记为modified状态(intelP6 family处理器采用),也可以直接写外部内存(intelPentium处理器采用)。
  2. 地址对应的cache line存在但被标记位了invalidate,同1是一样的。
  3. 地址对应的cache line存在,即write hit,和read hit略有不同的是,写完后需要将该cache line标记为modified
🍃 相关指令

cache一致性的维护由硬件CPU自动完成,同时处理器也会提供一些指令,以支持软件对cache的操作。以x86为例,有四条指令可以对cache进行invalidate/flush

  1. 全部invaliate/flush
  • WBINVD,即write back invalidate的缩写,具体操作是先将cache中标记为modified的内容全部write back到外部内存,再清空整个cache
  • INVD,相比WBINVD少了个write back的操作,所以没法保证数据一致性,这条指令只在cache和外部内存不需要保持一致的情况下使用(如某些测试环境)。
  1. 部分invalidate/flush
  • CLFLUSH/CLFLUSHOPT,即cache line flush的缩写,可针对某些cache lines单独操作,适用于该cache line对应的内存区域之后不会再被访问(access)到的情况。

转载:cache之读写一致性


CPU写入数据到L1/L2/L3 cache时,不会立刻写回主存。是否写回主存、何时写回主存,取决于CPUcache写策略(write policy),主要有以下两种:

🍃 Write-back(写回)

这是现代CPU默认且最常用的策略。

  • 数据先写入cache(如L1),不立即写回主存。
  • 对应的cache line被标记为dirty(脏)
  • 只有在以下情况之一发生时,才会写回主存:
    • cache line被替换(如LRU失效)
    • CPU显式执行flush操作(如CLFLUSH
    • 被其他核心通过一致性协议(如MESI)访问到,需要同步数据

优点: 减少对主存的访问频率,性能更高 缺点: 数据可能暂时不在主存中,掉电会丢失未写回的数据(除非通过其他手段备份)

​ ✅ 2. Write-through(直写)

  • 每次写入 cache 的同时,也写入主存
  • 不存在“脏”cache line。

优点: 数据主存始终是最新的 缺点: 每次写都会访问主存,性能较差

通常用于:

  • 某些嵌入式系统
  • L3 cache 或共享 cache 的某些配置
  • L1 instruction cache(通常是 read-only,不涉及 write)

⛳ 典型写入流程(Write-back 示例):

  1. CPU 执行 mov [addr], val
  2. 若地址命中 L1 cache,就在 L1 修改该 cache line,标为 dirty
  3. 等待某个时机再由 L1 写回到 L2 → L3 → 主存(逐层下推)
This post is licensed under CC BY 4.0 by the author.