缓存一致性


缓存架构

现代CPU都有多个核及多级缓存L1、L2、L3等,其中L1一般是每个核专用的,考虑简化的模型如下图:

一致性问题

假设CPU0 CPU1同时读了内存中的某段内容x=0,这时它们的缓存中都有该内容的副本0,然后CPU0将x的内容改为1,如下图:

这时如果CPU1需要再去访问x的值,但这时缓存中有x的值0,这时得到的值是旧值,也就出现了缓存不一致的情况。
显然,我们需要某种方法,当CPU0修改了x的内容时,需要使得其它缓存中能够同步,一种实现方法是硬件监听总线,当CPU0更新了缓存时会向总线广播消息通知其它CPU,当CPU1收到广播事件时,检查是否有相同的数据副本在自己的缓存中,如果有的话需要更新对应的缓存行的状态。

MESI协议

一种广泛使用的一致性协议是MESI协议,每个缓存行有4种状态,MESI是指4种状态的首字母,分别为:

状态 描述 监听任务
M 修改 (Modified) 该Cache line有效,数据被修改了,和内存中的数据不一致,数据只存在于本Cache中。 缓存行必须时刻监听所有试图读该缓存行相对就主存的操作,这种操作必须在缓存将该缓存行写回主存并将状态变成S(共享)状态之前被延迟执行。
E 独享、互斥 (Exclusive) 该Cache line有效,数据和内存中的数据一致,数据只存在于本Cache中。 缓存行也必须监听其它缓存读主存中该缓存行的操作,一旦有这种操作,该缓存行需要变成S(共享)状态。
S 共享 (Shared) 该Cache line有效,数据和内存中的数据一致,数据存在于很多Cache中。 缓存行也必须监听其它缓存使该缓存行无效或者独享该缓存行的请求,并将该缓存行变成无效(Invalid)。
I 无效 (Invalid) 该Cache line无效。

我们可以将MESI看成有限状态机:

模拟运行

  1. 初始状态CPU0~CPU3的L1 cache全为空,都处于I(Invalid)状态。
  2. CPU0读x的值,这是一次本地读,由于本地L1没有缓存数据x,这时会向总线发出读信号,看其它L1 cache是否有数据,由于其它cache这时也为空,因此只能向主存读取x的值并存在自己的缓存行中,并把状态改为E(Exclusive)
  3. CPU1读x的值,由于只有CPU0的缓存上有,因此CPU0把x的值发给CPU1,这时CPU0和CPU1都将缓存行的状态改为S(Shared)
  4. CPU2更新x的值,这时CPU2的缓存为空,会向总线询问其它CPU是否有缓存该数据。这时CPU0和CPU1发现自己都缓存了该数据,就将缓存行的状态改为I,CPU2收集完其它CPU的应答后,把CPU2的缓存行状态改为M(Modified).


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM