在 MESI 缓存一致性协议中,如果需要从内存中获取数据,缓存行的状态究竟何时发生变化?

In MESI cache coherence protocol, when exactly does the state of a cache line change if the data needs to be fetched from memory?

在 MESI 协议中 CPU:

需要从内存中获取数据。这将需要一定数量的周期来执行此操作。那么缓存行的状态是立即从(I)变为(E)还是仅在从内存中获取数据后才变为?

我认为缓存通常会等待数据到达当它还不存在时,您实际上无法在缓存中命中同一行的其他请求,只能命中实际存在的其他行(未命中时命中)。因此,该行的状态仍然无效;该标签的数据无效,因此您还不能将其设置为有效状态。

您希望同一行的另一个未命中(未命中下未命中)注意到该行已经有未完成的请求并将其自身附加到该行请求缓冲区。 (例如 Intel x86 LFB = 行填充缓冲区)。由于发现 Invalid 触发器会查看填充缓冲区,而 Exclusive 不会,因此您也需要基于此推理的 Invalid。

例如Skylake 性能计数器事件 mem_load_retired.fb_hit 计数,来自 perf list 输出:

[Retired load instructions which data sources were load missed L1 but hit FB due to preceding miss to the same cache line with data not ready.
Supports address when precise (Precise event)]

在没有内存级并行性的非常古老/简单或玩具 CPU 的缓存中(整个管道或只是内存访问完全停止执行,直到数据到达),区别是没有意义的;当请求的数据在传输中时,缓存不会发生任何其他事情。

在这样的 CPU 中,它只是一个实现细节。 (除非它仍然应该在负载运行时处理来自其他内核的 MESI 请求,因此标签需要再次反映正确的状态,否则在决定如何回复时需要检查额外的东西。)

从内存中获取数据后。

实际上,除了M/E/S/I的主要状态之外,MESI(或任何其他协议)还有许多过渡状态。在您的示例中,一致性协议将转换为 "Wait for Data Fill" 状态,并且仅在获取数据并设置有效位后才会转换为 E。

参考:gem5/ruby-- http://learning.gem5.org/book/part3/MSI/cache-transitions.html(搜索 "was invalid, going to shared")中的缓存一致性协议可能有用。