缓存一致性与MESI协议

摘要:
CPU将首先从缓存中查找数据,然后将数据从缓存加载到寄存器中进行计算。如果其他缓存中的副本通过总线无效,则必须首先从其他缓存或内存中获取最新值。其他缓存中的副本通过总线广播进行更新。监控协议的上述两种缓存写入策略解决了导致缓存一致性的核心问题。监控协议使用共享总线连接多个CPU的专用缓存和内存,具有有效副本的CPU将失效或更新此CPU上的数据。

对 于cpu来说,直接访问内存是比较耗时的,为了提高访问性能,现代计算机在cpu模块都加上了缓存(一般有3级缓存),cpu访问缓存的速度比直接访问内存的速度提高了很多。cpu在计算时会先从缓存中查找数据,如果在缓存中没有找到(缓存未命中),则从内存中查找并加载到缓存中,然后再把数据从缓存加载到寄存器中进行计算。

缓存一致性与MESI协议第1张

缓存一致性问题

在多核cpu的计算机中,缓存在提高了cpu访问速度的同时,也带来了相应的问题:
缓存一致性与MESI协议第2张

在上左图中,由于cpu1和cpu2都保存着同一缓存行x的拷贝,如果cpu1将x修改为1,则cpu1缓存中的x与cpu2缓存中的x,以及内存中的x的值是不一致的,这就是缓存一致性问题。接下来cpu2如果读取x,则读取的依然是x的旧值0(正确的情况下cpu读取的x应为新值1)。

在上右图中,由于可能发生cpu1和cpu2同时对x进行修改,这又会产生写顺序问题。如果cpu1和cpu2同时对x加1,最后都将值回写到了内存,则内存的值为1(正确的情况下x应为2),也就是说其中一个cpu对x加1这个计算是无效的。

解决一致性问题的两种缓存写策略

针对以上2个问题,可以提出2个一致性要求来解决:1.cpu的读操作必须能读到修改后的新值;2.cpu对同一缓存行的写操作不能同时发生。第1点保证了数据的一致性,第2点保证了写数据的顺序性。

有2种缓存的写策略可以满足以上一致性要求°?写无效策略可以同时满足以上2点,写更新策略是否可以满足第2点要求待证实,从而解决一致性问题。

  • 写无效:任一cpu在写某个数据时,会使其他cpu的缓存中的拷贝失效。在这种策略下,cpu写数据前,会先通过总线使其他缓存中拷贝失效,这就相当于取得了该数据的唯一访问权,因此接下来写数据就不会导致一致性问题。而其他cpu要读该数据时,由于该数据已失效,就必须先从其他缓存或内存中获得最新的值。
  • 写更新:任一cpu在写数据时,会通过总线广播使其他缓存中的拷贝进行更新。

缓存一致性与MESI协议第3张

由于写无效策略在性能上优于写更新策略,如对同一数据多个写而中间无读的情况,写更新需要多次写广播操作,而在写无效协议下只需一次写无效操作,因此,在基于总线的多核计算机中,写无效策略成为大多数系统设计的选择。

监听协议

上述的2种缓存写策略解决了导致缓存一致性的核心问题,但是还不够,若要完整的解决一致性问题,势必需要更加完整的方案,它们是:目录协议和监听协议。本文主要讲解监听协议。

监听协议使用共享总线连接多个cpu的私有缓存和内存,共享总线保证所有处理器内核的数据请求串行执行。任何处理器发出的数据请求将被广播到所有的cpu缓存控制器,所有cpu的缓存控制器都时刻监视着总线。如果收到读请求,数据所有者将把有效数据返回给发出此请求的cpu;如果收到写请求,拥有有效副本的cpu便无效或更新本cpu上的数据,数据所有者将把有效数据返回到发出此请求的cpu。数据所有者可能是cpu,也可能是内存。

如下图所示情景,cpu1发生写数据前,会把写请求广播到总线,此时cpu2的缓存控制器监听到此总线请求便会将x置为无效并给总线广播回复信号,cpu1收到回复信号确认其他cpu已将x的拷贝全部置为无效后,才会修改x。(如果cpu1,cpu2同时修改x,则必然其中一个cpu先获取总线控制权,之后它使cpu2的缓存上的拷贝失效。)接下来如果cpu2读取x,因为x是无效的状态,所以会向总线广播读请求,cpu1监听到该总线请求后会把x的内容通过总线传给cpu2的缓存。
缓存一致性与MESI协议第4张

MESI协议

概述

MESI协议是MSI的拓展协议,它是采用写回°@“写回”是一种规定了缓存在被修改后何时刷新至内存的策略,它规定仅当一个缓存块需要被替换回内存时,才将其内容写入内存。这意味着在缓存中被修改的数据可能不会被及时地写回内存。另外的一种策略为“写通”策略,它规定每当缓存接收到写数据指令,都直接将数据写回到内存,这种刷新内存的策略保证了被修改的缓存行能立即刷新至内存。和写无效策略的监听协议,被广泛用于维护缓存一致性。MESI指的是缓存行4个状态的首字母。

MESI协议包含的4个状态

状态描述
已修改Modified (M)缓存行是脏的(dirty),与主存的值不同。如果别的CPU内核要读主存这块数据,该缓存行必须回写到主存,状态变为共享(S).
独占Exclusive (E)缓存行只在当前缓存中,但是干净的(clean)--缓存数据同于主存数据。当别的缓存读取它时,状态变为共享;当前写数据时,变为已修改状态。
共享Shared (S)缓存行也存在于其它缓存中且是干净的。缓存行可以在任意时刻抛弃。
无效Invalid (I)缓存行是无效的

这些一致性状态通过高速缓存和内存之间的通信进行维护。 当缓存中的某行被读或写时,或者当缓存通过总线接收到其他缓存发出的读写信号时,它需要据此来做出动作并调整自己的状态。

当缓存收到cpu的读请求时,如果一个缓存行处于“M”或“S”状态,则它会直接提供数据。但如果缓存行尚未被加载到缓存(处于“I”状态),则在加载该缓存行之前,cpu中的缓存控制器会向总线广播这个读请求,在收到这个广播后,其他缓存中处于"E"状态的拷贝直接修改为“S"状态就可以了;而处于“M”状态的拷贝,则会将数据地址广播到总线,以供读请求的cpu拿到新数据,并且写回内存,在提供数据后,该拷贝修改为“S”状态。

当缓存收到cpu的写请求时,如果这缓存行处于"M"状态,则缓存只需要修改本地的数据。 如果缓存行处于"S"状态,则必须先将其他缓存中的拷贝置为“I”状态后,在修改本地的数据。 如果缓存行处于"I"状态,则其他处于”S"状态的拷贝只需将拷贝置为“I”状态;如果有一个拷贝处于"M"状态,那么它必须先将数据通过总线提供给请求数据的缓存,并写回内存,然后将拷贝置为“I”状态。如果此时缓存尚未装载该缓存行的数据,则修改前要先将其从内存中读取。在数据被修改之后,缓存行处于"M"的状态。

对于任何给定的两个缓存,如果他们具有对应相同地址的缓存行,则允许的状态如下表所示:

缓存一致性与MESI协议第5张

状态转换

MESI协议可以看作是一个有限状态机°@有限状态机(英语:finite-state machine,缩写:FSM)又称有限状态自动机(英语:finite-state automation,缩写:FSA),简称状态机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学计算模型。,它的4种状态转换来自两种场景:缓存所在处理器的读写,这种情景下处理器会向缓存发送读写请求;其他处理器的读写,这种情景下可能产生其他处理器向总线发送总线请求。

处理器向高速缓存发出的请求包括:

  • PrRd:处理器请求读取一个缓存块。
  • PrWr:处理器请求改写一个缓存块。

此外,还有总线方面的请求。 包括:

  • BusRd:当某个处理器的高速缓存的读操作出现未命中,它会向总线发送一个BusRd请求,并预期能够收到该缓存行的数据。
  • BusRdX:当某个处理器的高速缓存的写操作出现未命中,它会向总线发送一个BusRdX请求,预期能够收到该缓存行的数据,并且使其他处理器中对应相同地址的缓存行无效。
  • BusUpgr:当某个处理器的高速缓存的写操作命中时,它它会向总线发送一个BusUpgr,使其他处理器中对应相同地址的缓存行无效。
  • Flush:该请求表明一个缓存行正在被写回内存。

状态转移图

初始状态操作响应最终状态
     IPrRd
  • 给总线发BusRd信号
  • 其他处理器看到BusRd,检查自己是否有有效的数据副本,通知发出请求的缓存
  • 状态转换为S, 如果其他缓存有有效的副本
  • 状态转换为E, 如果其他缓存都没有有效的副本
  • 如果其他缓存有有效的副本, 其中一个缓存发出数据;否则从主存获得数据
     S
PrWr
  • 给总线发BusRdX信号
  • 状态转换为M
  • 如果其他缓存有有效的副本, 其中一个缓存发出数据;否则从主存获得数据
  • 如果其他缓存有有效的副本, 见到BusRdX信号后无效其副本
  • 向缓存块中写入修改后的值
     M
BusRd
  • 状态保持不变,信号忽略
     I
BusRdX/BusUpgr
  • 状态保持不变,信号忽略
     I
     EPrRd
  • 无总线事务生成
  • 状态保持不变
  • 读操作为缓存命中
     E
PrWr
  • 无总线事务生成
  • 状态转换为M
  • 向缓存块中写入修改后的值
     M
BusRd
  • 状态变为共享
     S
BusRdX
  • 状态变为无效
  • 发出总线FlushOpt信号并发出块的内容
     I
     SPrRd
  • 无总线事务生成
  • 状态保持不变
  • 读操作为缓存命中
     S
PrWr
  • 发出总线事务BusUpgr信号
  • 状态转换为M
  • 其他缓存看到BusUpgr总线信号,标记其副本为I
     M
BusRd
  • 状态变为共享
  • 可能发出总线FlushOpt信号并发出块的内容(设计时决定那个共享的缓存发出数据)
     S
BusRdX
  • 状态变为无效
  • 可能发出总线FlushOpt信号并发出块的内容(设计时决定那个共享的缓存发出数据)
      I
     MPrRd
  • 无总线事务生成
  • 状态保持不变
  • 读操作为缓存命中
     M
PrWr
  • 无总线事务生成
  • 状态保持不变
  • 写操作为缓存命中
     M
BusRd
  • 状态变为共享
  • 发出总线FlushOpt信号并发出块的内容,接收者为最初发出BusRd的缓存与主存控制器(回写主存)
     S
BusRdX
  • 状态变为无效
  • 发出总线FlushOpt信号并发出块的内容,接收者为最初发出BusRd的缓存与主存控制器(回写主存)
     I

缓存一致性与MESI协议第6张

举例说明

下面举个例子,来说明在MESI协议下,各个cpu是如何协同工作以保证缓存一致性的。

1.cpu1读取x(x的初始值为0)
• cpu1向缓存发出PrRd请求
• 由于读未命中(缓存C1尚未装载x,x的状态为I),cpu1的缓存控制器向总线广播BusRd请求
• 由于C2未装载x(x的x状态是I),所以会忽略掉总线请求(这种情况称为监听未命中),C1未收到其他cpu的回复信号,从内存中装载x,并将x状态设置为E

缓存一致性与MESI协议第7张

2.cpu2读取x
• cpu2向缓存发出PrRd请求
• 由于读未命中(C2尚未装载x,x的状态为I),cpu2的缓存控制器向总线广播BusRd请求
• cpu1的缓存控制器监听到总线请求(这种情况称为监听命中),将x的地址广播到总线上(用于将值传给C2),然后将x状态设置为S
• C2装载x,并将x的状态设置为S

缓存一致性与MESI协议第8张

3.cpu1修改x为1
• cpu1向缓存发出PrWr请求
• 由于写命中,cpu1的缓存控制器向总线广播BusUpgr请求,并将x的状态设置为M
• cpu2的缓存控制器监听到总线请求,将C2中的x的状态设置为I,并向总线广播回复信号
• cpu1收到回复信号,确认其他缓存将x的拷贝都已置为无效后,修改x

缓存一致性与MESI协议第9张

4.cpu2再次读取x
• cpu2向缓存发出PrRd请求
• 由于读未命中(C2中的x状态为I),cpu2的缓存控制器向总线广播BusRd请求
• cpu1的缓存控制器监听到总线请求,会暂时取得总线控制权,向总线广播FlushOpt请求并发出x的值(用于将x回写到内存和传给C2),然后将x的状态设置为S
• cpu2的缓存控制器再次取得总线控制权后,获得x的值(1),并将x的状态设置为S

缓存一致性与MESI协议第10张

免责声明:文章转载自《缓存一致性与MESI协议》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇读书笔记:深入理解ES6(十)session文件包含漏洞复现下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

Jenkins安装

1、 Jenkins简介1.开源自动化持续集成和部署平台CI、持续集成CD和持续部署2.Jenkins Free风格任务管道Maven项目多配置项目多分支管道任务支持的任务类型,不会执行任何更新;触发器(由Gitlab...

JavaScript算法学习:获取字符串最后一位方法及判断是否以指定字符串开始或结尾

Str.substr,其中start是必需的参数,表示坐标的起始位置。正值在正方向计数,负值在反方向计数,长度是可选参数,表示从起始位置开始计数的数字。...

uniapp打包h5 出现'连接服务器超时,点击屏幕重试'的页面

跟踪以首先找出原因全局组件AsyncErrorNew在中注册。js文件可以自定义。我很快就过去了,所以我添加了一个空白页面,然后在清单中介绍了组件。json文件...

electron用默认浏览器打开链接的3种实现方式

在使用Electron开发桌面程序的过程中,我们可能经常需要使Electron程序中包含的链接在单击后直接调用系统的默认浏览器打开。仔细阅读文档后,我们都知道它的核心原理是调用系统的默认浏览器,通过Electron shell模块中的openExternal方法打开链接。然而,它的实现有不同的方法,彻底接管和选择性接管。介绍第3章中的有效方法。以上三种方法都...

CefSharp 浏览器核心,爬虫

CefSharp是什么Aframeworkforembeddingweb-browsing-likecapabilitiestoastandard.NETapplication(WPForWindowsForms).Asetofhigh-levelcustomcontrolstomakeitreasonablyeasytointegratethesecapa...

Gidot TypeSetter (排版助手) 3.1.1.2

我们来看看:打开排版助手,可以看到常用的排版功能按钮排列在五个菜单选项下。图2如果您需要更高级的排版,也可以在界面右上角的“typesetting Widget”中进行设置。例如,如果您选择“网页”功能按钮来导入带有HTML代码的文本,您也可以从排版小部件中删除HTML代码功能。...