MSI:当共享状态和无效状态可以同时发生时

问题描述

所以,正如标题所说,是否有可能处理器 0 的 A 行具有共享 (S) 状态,而处理器 1 的 B 行具有无效 (I) 状态? >


想象以下情况:

  • P0:A 行 |修改
  • P1:A 行 |无效
  • P2:A 行 |无效

如果 P2 对 A 行发出读请求,那么 P1 的最终状态是什么?共享还是保持无效?

解决方法

TL;DR

P1 的 A 行仍将处于无效状态。其他处理器的操作无法更改无效状态。
P0 和 P2 的行 A 都处于共享状态。


Wikipedia's page for the MSI protocol 上有算法的状态机描述。
连同英文说明,有两张图片。

给定一组处理器及其相关的缓存线,处理器可以通过在“加载/读取”和“存储/写入”之间进行一个操作而处于“主动”状态,也可以通过监听事件而处于“被动”状态公交车。

MSI(和类似)协议的输入是一个动作或一个总线事件。为简单起见,维基百科将状态机分为两种:一种是当输入是动作时,一种是当输入是总线事件时。 这样你就可以用一张图来计算主动处理器(正好是一个)的线的新状态,而另一张图来计算被动处理器的线的状态。

假设处理器 X 是活动处理器,因此进行加载或存储。

第一张图描述了处理器 X(活动处理器)的缓存行状态如何变化:

enter image description here

每个标签都具有 x/y 形式,其中 x 是输入操作(PrRd 用于加载/读取或 PrWr 表示存储/写入),y 是发出的总线事件(“-”表示总线上没有发出任何事件)。

第二张图片的用法类似,但用于被动处理器(除处理器 X 之外的任何处理器):

enter image description here

这里的每个标签也是一个 x/y 对,但 x 是一个总线事件,而 y 是一个总线操作。

总线事件是:

  • BusRd -> 另一个处理器需要从内存(或上层缓存)读取一行。
  • BusRdX -> 另一个处理器需要从内存(或上层缓存)读取一行,但随后会立即修改它(即因为它正在执行写入)。
  • BugUpgr -> 另一个处理器刚刚写入了它的一个缓存行,该行目前仅被读取。

当然,Flush 是将一行写入内存的行为。维基百科认为它是一个总线事务(我认为它是一个总线操作,因为它不用作输入)。

我们现在可以回答您的问题了。


P2 是活动处理器,需要读取 A 行,因此它执行 PrRd。第一张图告诉我们它的线 A 将最终处于 S 状态,并且在总线上发出了一个 BusRd(注意这是一个心智模型,真实的硬件可能不会发送一个特殊的交易,而是它会检测读取本身)。

P2: LineA -> Shared

P0 和 P1 都是无源处理器,都可以看到 BusRd
P0 的行处于 Modified 状态,第二张图告诉我们它将刷新该行(使 P2 可以使用最后一个值)并将行 A 设置为状态 Shared。
P1 的行处于 Invalid 状态,从第二张图片我们看到,对于被动处理器,无法逃脱 Invalid 状态。具体来说,BusRd 输入会将 A 行的状态再次设置为 Invalid(实际上被忽略了)。

所以在从 P2 读取之后,我们有:

P0: LineA -> Shared
P1: LineA -> Invalid
P2: LineA -> Shared