此答案适用于具有包容性 L3 缓存和 Sandy Bridge 样式环形总线(即不是 Nehalem/Westmere EX 之一)的 Intel CPU,这是从 Sandy Bridge 到 Skylake 服务器之前的所有服务器 CPU。
普遍说Intel用的是MESIF,但是AFAICT,内核中不存在F状态。核心 (*) 行将处于 MESI 状态,因为在包含 L3 缓存的情况下,如果数据存在于 1 个以上的核心中,则直接从 L3 中读取数据。不需要专用的 F 状态。然而,它确实存在于具有非包含 L3 的 Skylake 服务器的核心中。
内核将 IDI 数据包发送到处理该地址范围的 L3 高速缓存片 Cbo(控制器)(它基于地址的高速缓存集选择器位的上部的哈希函数以 CBo 的数量为模进行交错) .当核心请求一条不属于核心的线路时,核心会发送一个 DRd 数据包,如果它存在于其他核心中,它会以 S 状态接收它,或者如果它不存在于其他核心中,它会以 E 状态接收它。 L3 高速缓存切片 Cbo 对线路使用 snoop 过滤器来决定是在 E 状态(在没有其他核心但在 L3 中/不在 L3 中)或 S 状态(在 L3 中并存在于另一个核心中;发送降级到那个核心 E->S)。如果行的第一个请求不属于其他内核,则默认为 E 状态而不是 S 状态是一种优化,因为内核不必执行 RFO,因为 L3 缓存片的轻微缺陷具有向核心发送降级(与执行 RFO 会导致的实际延迟相比,这只是后台的额外流量)。
当线路完全不拥有时,RFO 数据包被发送到 LLC 切片 Cbo,因为内核即将对其执行写入,在这种情况下,如果 CBo 拥有,则需要发送无效在多个核中,或者如果它只在一个核中拥有,则监听无效,因为 CBo 不知道这是否被修改,以及跨套接字监听拥有地址的家乡代理,并返回线到核心以及升级它。当线路在 S 状态下被拥有时,它会向 L3 切片 CBo 发送写入无效WiL,然后它将使其他内核无效并将请求者升级到 E 状态。它导致 S 状态变为 E 并使其他内核无效。想必在数据包中有一个标志表明它处于S状态,以消除不必要的负载。
F状态只针对L3缓存(缓存代理)在其他缓存代理和主节点中的家乡代理之间进行多套接字侦听的上下文中,因为家乡代理HitME缓存不包含任何套接字的L3 .在没有目录的源探听模式下,只有一个缓存代理(NUMA 节点中的一组 CBos)将响应广播探听,如果它具有 F 状态,而不是导致多个响应。在带有目录缓存 + 目录的 home snoop 模式下,目录缓存 + 目录位意味着在可能的情况下,无论如何只会发送一个请求,但是当它没有被缓存并且发送广播时,F 状态会有所帮助,因为那里不是多重响应。因为缓存可能会单方面丢弃(无效)处于 S 或 F 状态的行,所以即使存在 S 状态的副本,也可能没有缓存具有处于 F 状态的副本。在这种情况下,从主内存(因为没有缓存代理会在它们处于 S 状态时响应)满足(效率较低,但仍然正确)对行的请求。
“本地节点本地代理”是 SAD 解码的一致 DRAM 地址交错到的本地代理(即拥有该地址的本地代理)。
IDI 操作码(用于核心非核心通信)在 2014 年 Xeon E5 v2s 性能监控手册中没有显示任何 F 状态(只有 QPI 操作码有,它谈论缓存代理和本地代理,并且是用于非核心非核心通信),但 2017 年性能监控手册显示 IDI 操作码也处理 F 状态,即 WbEFtoE 和 WbEFtoI 并谈论“核心”。在文档中搜索 skylake 会显示 skylake 服务器的结果,其中包含一个非包容性 L3,这说明了一切。
由于 L2 在最新的 Intel 台式机 CPU 上不包含在内,它可能意味着 L1i 和 L1d 实现了自己的 F 状态,这可以由 L2 在其支持的 2 个缓存之间在内部使用( L1i,L1d,由内核中的两个超线程共享)用于缓存未命中,尽管如果 L1d 和 L1i 缓存能够在内部相互查询/无效,则这不是必需的,这似乎比转到 L2 然后 L2 必须更快查询请求不是来自的缓存,并且只有一个其他缓存要查询,尽管我实际上不认为 L1i 和 L1d 是一致的,除了存在任何 SMC 实现(自我修改代码),我不了解详情。 L2 缓存当然不需要 F 状态。