MESI 协议

MESI协议是解决多CPU环境下缓存一致性问题的关键,它定义了Modified、Exclusive、Shared和Invalid四种缓存状态。协议采用回写策略和缓存无效化,但在本地写操作后需等待其他CPU确认,可能导致同步阻塞和指令重排序。为提高效率,可以使用异步处理,但牺牲了一致性。当需要强一致性时,需要考虑额外措施,如避免CPU重排序。

一、概念

MESI 协议是高速缓存一致性协议,是为了解决多 cpu 、并发环境下,多个 cpu 缓存不一致问题而提出的协议。

协议规定,缓存行在任何时刻一定处于四个状态之一:

  • Modified: 缓存行已经被修改,但是没有被写回主存;
  • Exclusive: 缓存行与主存相同,并且是主存的唯一拷贝;
  • Shared: 缓存行与主存相同,可能也存在于其他的缓存中,并不是主存的唯一拷贝;
  • Invalid: 缓存行无效

MESI 状态转换:

二、特点

MESI  是一种基于回写(write-back)、缓存无效化(invalidate)的协议。

回写:本地修改并不会立即同步到主存(write-through),而是等到出现 dirty 数据被交换出来时才同步;

缓存无效:一旦某个cpu 发生了本地写,会广播一个 “invalid message”,其它cpu 会将本地缓存重置为无效。

三、一致性问题

在某个 cpu 发生本地写事件后,需要通过总线发送 invalid message, 等到其他的cpu 完成invalid 本地缓存后并 ack ,这个cpu 才能真正地修改缓存然后继续向下执行,这个过程是同步阻塞的,也被成为缓存锁

图片

这样做的好处是保证了缓存间的强一致性,但是效率低,优化思路很简单,就是通过缓存、队列来实现异步,提高了效率,但是牺牲了强一致性,而且还会出现指令重排的现象!!

比如:

a = 1;
b = a + 1;
assert(b == 2);

会把 a = 1 放入 store buffer 发送 invalidate 消息并得到 ack, 继续执行了 b = a +1, a 从主存重新读取仍然是默认的 0 , 所以 b = 1, 断言失败, cpu 表现出来了重排序执行效果:

b = a + 1;
a = 1;
assert(b == 2);

另外 invalid queue 和 store buffer 也有溢出的风险。

图片

这个时候如果确实需要禁止 cpu 重排序,保证强一致性怎么办呢?大家思考一下,下篇文章会给出答案!


如果觉得还不错的话,关注、分享、在看, 原创不易,且看且珍惜~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

【非典型Coder】

赏个鸡腿吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值