CPU缓存一致性
数据一致性问题
缓存一致性协议——MESI协议
MESI(Modified, Exclusive, Shared, Invalid)是一种常见的缓存一致性协议,是⼀个基于失效的缓存⼀致性协议,是⽀持写回(write-back)缓存的最常⽤协议。也称作伊利诺伊协议 (Illinois protocol,因为是在伊利诺伊⼤学厄巴纳-⾹槟分校被发明的)。
为了解决多个核心之间的数据传播问题,提出了总线嗅探(Bus Snooping)策略。本质上就是把所有的读写请求都通过总线(Bus)广播给所有的核心,然后让各个核心去嗅探这些请求,再根据本地的状态进行响应。用于多处理器系统中维护缓存的一致性。MESI协议基于每个缓存行维护的四个状态来实现缓存的一致性:
状态 | 描述 | 监听任务 |
---|---|---|
M 修改(Modified) | 该Cache line有效,数据被修改了,和内存中的数据不一致,数据只存在于本Cache中。 | 缓存行必须时刻监听所有试图读该缓存行相对就主存的操作,这种操作必须在缓存将该缓存行写回主存并将状态变成S(共享)状态之前被延迟执行。 |
E 独享、互斥(Exclusive) | 该Cache line有效,数据和内存中的数据一致,数据只存在于本Cache中。 | 缓存行也必须监听其它缓存读主存中该缓存行的操作,一旦有这种操作,该缓存行需要变成S(共享)状态。 |
S 共享(Shared) | 该Cache line有效,数据和内存中的数据一致,数据存在于很多Cache中。 | 缓存行也必须监听其它缓存使该缓存行无效或者独享该缓存行的请求,并将该缓存行变成无效(Invalid)。 |
I 无效 (Invalid) | 该Cache line无效。 | 无 |
缓存写策略
从缓存和内存的更新关系来看,分为:
- 写回(write-back)对缓存的修改不会立刻传播到内存,只有当缓存行被替换时,这些被修改的缓存行才会写回并覆盖内存中过时的数据。
- 写直达(write through)缓存中任何一个字节的修改,都会立刻穿透缓存直接传播到内存,这种比较耗时。
从写缓存时 CPU 之间的更新策略来看,分为:
- 写更新(Write Update)每次缓存写入新的值,该核心必须发起一次总线请求,通知其他核心更新他们缓存中对应的值。
- 坏处:写更新会占用很多总线带宽;
- 好处:其他核心能立刻获得最新的值。
- 写无效(Write Invalidate)每次缓存写入新的值,都将其他核心缓存中对应的缓存行置为无效。
- 坏处:当其他核心再次访问该缓存时,发现缓存行已经失效,必须从内存中重新载入最新的数据;
- 好处:多次写操作只需发一次总线事件,第一次写已经将其他核心缓存行置为无效,之后的写不必再更新状态,这样可以有效地节省核心间总线带宽。
从写缓存时数据是否被加载来看,分为:
- 写分配(Write Allocate)在写入数据前将数据读入缓存。当缓存块中的数据在未来读写概率较高,也就是程序空间局部性较好时,写分配的效率较好。
- 写不分配(Not Write Allocate)在写入数据时,直接将数据写入内存,并不先将数据块读入缓存。当数据块中的数据在未来使用的概率较低时,写不分配性能较好。
MESI状态机
触发事件 | 描述 |
---|---|
本地读取 (Local read) | 本地cache读取本地cache数据 |
本地写入 (Local write) | 本地cache写入本地cache数据 |
远端读取 (Remote read) | 其他CPU内核读取了DRAM中当前内核的缓存行 |
远端写入 (Remote write) | 其他CPU内核写入了DRAM中当前内核的缓存行 |
多核缓存协同操作
MESI协议的基本工作原理如下:
- 当一个处理器读取一个缓存行时,会先检查该缓存行的状态。如果状态是Modified或Exclusive,表示该处理器已经拥有了最新的数据,可以直接读取。如果状态是Shared,表示还有其他处理器也在拥有该缓存行,需要进行一致性操作。
- 当一个处理器写入一个缓存行时,会将该缓存行的状态设置为Modified,并将该写操作标记为自己的专用数据。
- 在发生缓存一致性操作时,MESI协议会通过一些特定的消息(如请求、响应、授权等)来进行通信和同步,以保证缓存的一致性。这些消息会在处理器之间传递,允许缓存行状态的转换和数据的更新。
MESI协议确保了多处理器系统中缓存的一致性,避免了数据的不一致性和错误的结果。它在多处理器系统中被广泛应用,以提供高效的共享数据访问和一致性保证。
假设有三个CPU A、B、C,对应三个缓存分别是cache a、b、 c。在主内存中定义了x的引用值为0。
单核读取
CPU A发出了一条指令,从主内存中读取x。从主内存通过bus读取到缓存中(远端读取Remote read),这是该Cache line修改为E状态(独享).
![]() |
![]() |
![]() |
双核读取
CPU A发出了一条指令,从主内存中读取x。
CPU A从主内存通过bus读取到 cache a中并将该cache line 设置为E状态。
CPU B发出了一条指令,从主内存中读取x。
CPU B试图从主内存中读取x时,CPU A检测到了地址冲突。这时CPU A对相关数据做出响应。此时x 存储于cache a和cache b中,x在chche a和cache b中都被设置为S状态(共享)。
双核修改
CPU A 计算完成后发指令需要修改x.
CPU A 将x设置为M状态(修改)并通知缓存了x的CPU B, CPU B将本地cache b中的x设置为I状态(无效)
CPU A 对x进行赋值。
双核同步
CPU B 发出了要读取x的指令。
CPU B 通知CPU A,CPU A将修改后的数据同步到主内存时cache a 修改为E(独享)
CPU A同步CPU B的x,将cache a和同步后cache b中的x设置为S状态(共享)。
参考文献
【1】 https://cloud.tencent.com/developer/article/2352029?areaId=106001
-
免责声明
- 本文发布的信息,最终解释权归作者所有,如有疑问或需要进一步了解,请直接与作者联系。
- 本文部分信息来源于网络,其版权归原作者所有,本文使用该信息仅出于分享给求职者,无任何商业用途,如有侵权,请联系作者删除。
- 本文发布的信息旨在为应届生和社会人士提供了解相关企业招聘信息的便利,不涉及任何机密信息,且所有信息均为网络公开获取。 本人亦无任何渠道可以了解任何机密信息, 如果您认为某些内容存在侵权、泄密问题,请及时联系作者删除。
若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏

更多央国企信息、面试辅导、简历修改等,请关注知识星球:[成都央国企指南]