码迷,mamicode.com
首页 > 其他好文 > 详细

MESY协议

时间:2021-04-16 12:19:07      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:核心   方案   code   发送   操作   无效   并发   har   包括   

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

技术图片

缓存一致性问题

在多核cpu的计算机中,缓存在提高了cpu访问速度的同时,也带来了相应的问题:
技术图片

在上左图中,由于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点要求,从而解决一致性问题。

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

技术图片

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

监听协议

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

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

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协议可以看作是一个有限状态机,它的4种状态转换来自两种场景:缓存所在处理器的读写;其他处理器的读写。

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

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

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

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

状态转移图

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

技术图片
举例说明

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

1.cpu1,x的初始值为0

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

技术图片
2.cpu2读取x(0)

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

技术图片

2.cpu1修改x,将x修改为1。

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

技术图片

3.cpu2读取x,读取x(1)。

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

技术图片

 

MESY协议

标签:核心   方案   code   发送   操作   无效   并发   har   包括   

原文地址:https://www.cnblogs.com/wql025/p/14665177.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!