经典内存系统一致性
M5 2.0b4 引入了一个经过大幅重写和精简的缓存模型,包括一个新的相干性协议。(旧的 2.0 之前的缓存模型已被修补以与 2.0beta 中引入的新 内存系统 一起工作,但没有重写以利用新内存系统的功能。)
新一致性协议的关键特性是它旨在与差不多任意的缓存层次结构(多个级别上的多个缓存)一起工作。相比之下,旧协议限制共享单个总线。
在现实世界中,系统架构对协议设计所能适应的缓存数量或配置有限制。设计一个既完全逼真又对任意配置高效的协议是不切实际的。为了使我们的协议能够在(几乎)任意配置上工作,我们目前牺牲了一点真实性和一点可配置性。我们的意图是,此协议对于研究系统行为方面而不是一致性机制的研究人员来说已经足够了。专门研究一致性的研究人员可能希望用正在调查的特定协议的实现替换默认的一致性机制。
该协议是一个 MOESI 监听协议。包含 未 强制执行;在 CMP 配置中,如果您有多个 L1,其总容量占它们共享的公共 L2 容量的很大一部分,包含可能会非常低效。
来自上层缓存(更靠近 CPU 的那些)的请求以预期的方式向内存传播:L1 未命中在本地 L1/L2 总线上广播,在那里它被该总线上的其他 L1 监听,并(如果没有响应)由 L2 服务。如果请求在 L2 中未命中,那么在一些延迟(目前设置为等于 L2 命中延迟)之后,L2 将在其内存侧总线上发出请求,在那里它可能被其他 L2 监听,然后发布到 L3 或内存。
不幸的是,以类似的方式将 snoop 请求逐级向上传播到层次结构中是无数几乎棘手的竞争条件的来源。无论如何,真实系统通常不会这样做;通常,您希望在 L2 总线处进行一次 snoop 操作,以告知您整个 L1/L2 层次结构中块的状态。有几种方法可以做到这一点:
- 只监听 L2,但强制包含,以便 L2 也拥有您需要的有关 L1 的所有信息——我们已经在上面拒绝了这个想法
- 在 L2 处为所有 L1 保留一组额外的标记,以便可以同时监听这些标记(参见 Compaq Piranha)——如果您的层次结构不太深,这是合理的,但现在您必须根据上层缓存的数量、大小和配置来确定下层缓存中标记的大小,这是一个配置痛苦
- 与 L2 并行监听 L1,如果它们都在同一个芯片上,这并不难(我相信 Intel 从 Pentium Pro 开始就这样做了;不确定他们是否还在 Core2 芯片上这样做,或者 AMD 是否也这样做,但我怀疑是这样)——也是合理的,但为这些 snoop 添加显式路径也会导致非常繁琐的配置过程
我们通过引入“express snoops”来解决这一困境,这是一种特殊的 snoop 请求,即使系统在 timing 模式下运行,它也能瞬间且原子地向上传播到层次结构中(很像 内存系统 页面上描述的 atomic 模式访问)。在功能上,这非常类似于上面的选项 2 或 3,但由于 snoop 沿着常规总线互连传播,因此没有额外的配置开销。引入了一些时序不准确性,但如果我们假设真实硬件中有用于这些 snoop 的专用路径(或者用于在下层缓存处维护上层标记的额外副本),那么差异可能很小。
(更多内容即将到来:缓存如何知道其请求何时完成?以及其他引人入胜的问题……)
注意:截至 2.0b4,此协议中仍有一些错误,特别是如果您有多个 L2,每个 L2 后面有多个 L1,但我相信它适用于任何在 2.0b3 中工作的配置。
