Skip to content

算法Algorithm

MSI 缓存一致性协议

MSI cache coherence · Atomic-bus MSI protocol

在原子串行总线模型中完整执行I/S/M转移,追踪独占权限、脏数据来源和失效。

形式陈述 ​

MSI用每块的I(Invalid)、S(Shared)、M(Modified)状态实现缓存一致性契约。本文明确选用教学变体:所有总线事务串行且原子完成,不存在未完成请求交错;S副本与内存一致,M是唯一有效读写副本、可能比内存新。每个原子事务结束后才观察稳定状态。

请求有BusRd(申请读副本)、BusRdX(取得数据及独占权限)、BusUpgr(已有S副本,申请独占权限)。BusRdX遇旧M时,旧主既供最新数据也更新内存,然后失效;这是本文的显式选择,其他实现可以有不同的数据转发方式。

本核心事件 ​

旧状态 读 写 逐出
I BusRd取最新块,转S再读 BusRdX取块并使他方失效,转M再写 保持I
S 本地读,保持S BusUpgr使他方S失效,转M再写 静默转I
M 本地读,保持M 本地写,保持M 最新整块写回,转I

监听其他核心事务 ​

旧状态 他方BusRd 他方BusRdX 他方BusUpgr
I 不动作 不动作 不动作
S 保持S 失效为I 失效为I
M 供最新数据并更新内存,转S 供最新数据并更新内存,转I 合法稳定状态中不应发生

M与他方S不能共存,而BusUpgr只能由S发起,所以最后一个组合不可达。它应当被断言检查,而不是随意补一条掩盖协议错误的正常转移。

直觉

S可以让多个人读,M把写权收拢到一个人,I禁止使用残留旧值。从S升级只需收回别人的权限;从I写入还要取得完整数据,以保留本次没覆盖的字节。

三状态图只描述本文事务完成后的观察点。若把请求发送、仲裁、数据返回和失效确认拆成独立消息,就必须增加等待与竞争状态;不能用这张图直接声称分裂总线已经无竞态。

例子与边界

三个核心转交一个word ​

内存初值0,P/Q/R均I。下面每行是一个完整事件之后的状态;括号内为有效副本的值。

操作 P Q R 内存 总线动作
P读 S(0) I I 0 BusRd
Q读 S(0) S(0) I 0 BusRd
P写1 M(1) I I 0 BusUpgr
R读 S(1) I S(1) 1 BusRd;P供数据并写回
Q写2 I M(2) I 1 BusRdX;P/R失效
Q逐出 I I I 2 脏回写

第四步R不能从尚为0的内存直接读旧值;必须由M的最新数据修正此次响应。第五步Q取得完整块后再改目标word,保留块内其他字节。

只画原子事务前后的稳定状态;M供数后才能让新读者使用数据

两个最短错误轨迹 ​

省略第三步的失效:P成M(1),Q仍S(0),Q下一次本地读就得到旧0,且读写权限同时存在。省略第四步的M供数:状态表可以写成两个S,但R读到0、P保留1,数据不变量仍被破坏。只检查M数量不超过一,抓不到第二种错误。

推论与应用

把按已完成写操作更新的最新抽象块记为 V。归纳不变量是:至多一个M;有M时其他核心全I且M持有 V;无M时内存和所有S均为 V。初始内存为初值、各缓存I,所以成立。合法本地读取得 V,不改状态;M本地写同时更新自身与抽象 V,其他核心仍I。

I读若遇M,原M把 V 交给请求者并写入内存,双方转S;若无M则从含 V 的内存取数。申请独占时,I请求先从旧M或内存取得 V,S升级本来已持有 V,随后原子失效其他副本,再执行本地写并更新 V,于是只剩新M。M逐出把 V 写到内存后转I;S静默逐出不改变其余值。表中所有合法事件都落在这些情况内,故不变量按事件数归纳保持。

这份证明依赖事务原子完成的观察边界,有限状态穷举只能补充检查实现是否忠于规则。总线最终是否服务每个请求还需要公平调度假设,安全不变量本身不保证进展。

本页不提供跨地址排序或持久化保证。内存模型和掉电恢复仍有各自的契约;把状态名换成MESI也不会自动补齐这些保证。

参考资料
关系图谱6 个相邻概念 · 3 类关系

拖动节点调整位置。

显示关系

显示:依赖

  1. 前置三跳
  2. 前置二跳
  3. 前置一跳
  4. 当前条目
  5. 后续一跳
  6. 后续二跳
  7. 后续三跳
文字版关系按与当前条目的最短距离分组
类型化关系