MESI协议

MESI协议是一个基于失效的快取一致性协议，是支持写回（write-back）快取的最常用协议。也称作伊利诺伊协议 (Illinois protocol，因为是在伊利诺伊大学厄巴纳-香槟分校被发明的)。与写直达（write through）快取相比，回写缓冲能节约大量带宽。总是有“脏”（dirty）状态表示快取中的数据与主存中不同。MESI协议要求在快取不命中（miss）且数据块在另一个快取时，允许快取到快取的数据复制。与MSI协议相比，MESI协议减少了主存的事务数量。这极大改善了性能。

 状态 
快取行有4种不同的状态:

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

任意一对快取，对应快取行的相容关系:
     M    E    S    I   M               E               S               I             
当块标记为 M (已修改), 在其他快取中的数据副本被标记为I(无效).

 操作 
MESI协议的状态图
红色: 总线初始化事务；
蓝色: 处理器初始化事务
有限状态自动机的状态转换结束两种场景：快取所在处理器的读写；其他处理器的读写。总线请求被监视。

处理器对快取的请求:
 PrRd: 处理器请求读一个快取块
 PrWr: 处理器请求写一个快取块
总线对快取的请求:
 BusRd: 窥探器请求指出其他处理器请求读一个快取块
 BusRdX: 窥探器请求指出其他处理器请求写一个该处理器不拥有的快取块
 BusUpgr: 窥探器请求指出其他处理器请求写一个该处理器拥有的快取块
 Flush: 窥探器请求指出请求回写整个快取到主存
 FlushOpt: 窥探器请求指出整个快取块被发到总线以发送给另外一个处理器（快取到快取的复制）

解释

图1.1是MESI协议四种状态的转换图。
+表1.1 处理器操作带来的状态转化初始状态操作响应 Invalid(I)PrRd 给总线发BusRd信号
 其他处理器看到BusRd，检查自己是否有有效的数据副本，通知发出请求的快取
 状态转换为(S)Shared, 如果其他快取有有效的副本
 状态转换为(E)Exclusive, 如果其他快取都没有有效的副本
 如果其他快取有有效的副本, 其中一个快取发出数据；否则从主存获得数据PrWr 给总线发BusRdX信号
 状态转换为(M)Modified
 如果其他快取有有效的副本, 其中一个快取发出数据；否则从主存获得数据
 如果其他快取有有效的副本, 见到BusRdX信号后无效其副本
 向快取块中写入修改后的值 Exclusive(E)PrRd 无总线事务生成
 状态保持不变
 读操作为快取命中PrWr 无总线事务生成
 状态转换为(M)Modified
 向快取块中写入修改后的值 Shared(S)PrRd 无总线事务生成
 状态保持不变
 读操作为快取命中PrWr 发出总线事务BusUpgr信号
 状态转换为(M)Modified
 其他快取看到BusUpgr总线信号，标记其副本为(I)Invalid. Modified(M)PrRd 无总线事务生成
 状态保持不变
 读操作为快取命中PrWr 无总线事务生成
 状态保持不变
 写操作为快取命中
+表1.2 不同总线操作带来的状态转化初始状态操作响应 Invalid(I)BusRd 状态保持不变，信号忽略BusRdX/BusUpgr 状态保持不变，信号忽略 Exclusive(E)BusRd 状态变为共享
 发出总线FlushOpt信号并发出块的内容BusRdX 状态变为无效
 发出总线FlushOpt信号并发出块的内容 Shared(S)BusRd 状态变为共享
 可能发出总线FlushOpt信号并发出块的内容（设计时决定哪个共享的快取发出数据）BusRdX 状态变为无效
 可能发出总线FlushOpt信号并发出块的内容（设计时决定哪个共享的快取发出数据） Modified(M)BusRd状态变为共享
 发出总线FlushOpt信号并发出块的内容，接收者为最初发出BusRd的快取与主存控制器（回写主存）BusRdX 状态变为无效
 发出总线FlushOpt信号并发出块的内容，接收者为最初发出BusRd的快取与主存控制器（回写主存）

写操作仅在快取行是已修改或独占状态时可自由执行。如果在共享状态，其他快取都要先把该快取行置为无效，这种广播操作称作Request For Ownership (RFO).

快取对已修改状态的快取行，要监听各处理器对其的读请求并插入其数据到总线。

快取对共享状态的快取行，要监听使其无效或请求拥有的广播，当匹配时把该快取行置为无效。

已修改状态、独占状态是精确的，匹配于该快取行在系统中的实际情况。共享状态可以是不精确的: 如果别的快取抛弃了该行，只有当前快取拥有该行，但其状态没有变为独占。其他快取不需要广播通知其抛弃操作。 

独占状态是一个优化机会：处理器修改共享状态的快取行必须要先发出一个总线事务使得其他快取中的该行失效；而独占状态下修改一行不需要总线事务。 

MESI协议操作图解

假定下述读/写操作访问同一主存位置的数据。操作流是 : R1, W1, R3, W3, R1, R3, R2. 最初所有快取为空。
+表 1.3 MESI工作举例
所有操作引用同一快取行

(例如: "R3" 值处理器3的读操作)本地 请求P1P2P3产生的
总线请求数据提供者0最初-----1R1E--BusRdMem2W1M----3R3S-SBusRdP1's Cache4W3I-MBusUpgr-5R1 S-SBusRdP3's Cache6R3S-S--7R2SSSBusRd P1/P3's Cache

参见 

Dragon协议

 参考文献 

外部链接
 An interactive MESI simulation 
 An open source MESI controller (Verilog) 

Category:快取一致性