CPU缓存一致性协议MESI 学习笔记

学习内容链接https://www.cnblogs.com/yanlong300/p/8986041.html(原文写的非常好,建议看原文。这里仅仅是自己学习后,再梳理一遍增加印象~)

 

为什么有MESI协议?

CPU的计算能力与日俱增,然而内存及硬盘的发展速度远远落后于CPU,CPU厂商为了解决这个问题在CPU内增加了少量告诉缓存来匹配CPU的计算速度。随着计算机的硬件架构逐渐走向了多缓存(时间局部性、空间局部性)多核心的结构。为了保证计算中缓存内部数据的一致性,提出了一个MESI协议来解决这个问题。

1195582-20180503162457455-1411867425.png (670×700)

什么是MESI协议?

多核CPU的情况下有多个一级缓存,如何保证缓存内部数据的一致,不让系统数据混乱。这里就引出了一个一致性的协议MESI来解决这个问题。
MESI指的是:

M(Modified 修改)、E(Exclusive 独享)、S(Shared 共享)、 I(无效 Invalid) 四种状态的首字母。

 

多核缓存协同操作示例

假设有三个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状态(共享)。

缺陷: 一个数据被修改前,将其他CPU的缓存数据修改成无效状态。需要其他CPU进行处理。需要进行数据修改的CPU在等待其他所有CPU回复的时间会很长。会导致各种性能问题及稳定性问题。

 

更优方法:存储缓存store buffers

存储缓存模型为了解决MESI协议存在的效率问题被引入。在有CPU想修改变量值时,会先将数据写入到存储缓存中,然后切换去处理其他事情。当收集齐了其他CPU的失效标识时,再将修改的数据写入到主内存中。这样提升了CPU的计算时间。

 

Store buffers的风险

  1. cpu会尝试从存储缓存中优先读取数据。
  2. 存储在存储缓存中的数据什么时候进行同步没有保证。

 

试想一下开始执行时,CPU A保存着finished在E(独享)状态,而value并没有保存在它的缓存中。(例如,Invalid)。在这种情况下,value会比finished更迟地抛弃存储缓存。完全有可能CPU B读取finished的值为true,而value的值不等于10。

即isFinsh的赋值在value赋值之前。

这种在可识别的行为中发生的变化称为重排序(reordings)。注意,这不意味着你的指令的位置被恶意(或者好意)地更改。

它只是意味着其他的CPU会读到跟程序中写入的顺序不一样的结果。

 

Store buffers风险的解决方案

Store buffers 并不是无限的,等待失效消息也是一个开销。一样也会吃掉很多性能。为了解决该情况约定:

  • 对于所有的收到的Invalidate请求,Invalidate Acknowlege消息必须立刻发送
  • Invalidate并不真正执行,而是被放在一个特殊的队列中,在方便的时候才会去执行。
  • 处理器不会发送任何消息给所处理的缓存条目,直到它处理Invalidate。

干脆处理器将这个任务丢给了写代码的人(操作系统层面进行处理)。这就是内存屏障(Memory Barriers)。

写屏障 Store Memory Barrier(a.k.a. ST, SMB, smp_wmb)是一条告诉处理器在执行这之后的指令之前,应用所有已经在存储缓存(store buffer)中的保存的指令。

读屏障Load Memory Barrier (a.k.a. LD, RMB, smp_rmb)是一条告诉处理器在执行任何的加载前,先应用所有已经在失效队列中的失效操作的指令

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值