![]() |
1
6
一般来说,现代CPU使用一些变体 1. 的 MESI 保持缓存一致性的协议。 在一级写入场景中,细节取决于缓存线的现有状态:缓存线是否已经在写入核心的缓存中?在另一个核心中,缓存线处于什么状态,例如,它是否已被修改? 让我们来看一个简单的例子,其中行不在写核(C1)中,而在另一个核(C2)中处于“独占”状态。在写入地址已知的点,C1将在“总线”上发出RFO(所有权请求)事务,其中包含线路地址,其他核心将 snoop 总线并通知事务。另一个具有该线的核心将从 独家 到 无效的 线路的状态和值将提供给请求的核心,该核心将在 被改进的 状态,此时可以继续写入。 注意,在这一点上,从写入核心到该行的进一步写入将快速进行,因为它处于M状态,这意味着不需要发生总线事务。在线路被逐出或其他一些核心请求访问之前,情况将一直如此。 现在,在实际实现中有很多额外的细节,上面甚至维基百科对该协议的描述中都没有涵盖。 例如,基本模型涉及每个CPU一个专用缓存和共享主内存。在这个模型中,核心C2通常会在总线上提供共享线路的值,即使它没有修改它,因为这比等待从主存读取值要快得多。然而,在所有最近的x86实现中,都存在一个 共享 最后一级三级缓存,位于所有私有二级和一级缓存与主内存之间。此缓存通常是 inclusive 因此,它可以直接向C1提供值,而不需要从C2进行缓存到缓存的传输。此外,拥有此共享缓存意味着每个CPU实际上可能不需要嗅探“总线”,因为可以首先查看三级缓存以确定哪些内核(如果有的话)实际具有该线路。然后,只有具有该行的内核才会被要求进行状态转换。这是一种推动模式,而不是拉动模式。 尽管有所有这些实现细节,但基本原理是相同的:每个缓存线都有一些“每核”状态(即使该状态可以存储或复制在诸如LLC之类的中心位置),并且该状态在原子上经历逻辑转换,以确保缓存线始终保持一致。 在这种背景下,以下是对最后两个子问题的一些具体回答:
任何现代内核都将实时完成这项工作,并且对于不同的缓存线也是并行的。这并不意味着它是免费的!例如,在上面的描述中,C1的写入暂停,直到缓存一致性协议完成,这可能需要几十个周期。与之相比,普通写入只需要几个周期。还可能存在带宽问题:用于实现协议的请求和响应使用可能具有最大吞吐量的共享资源;如果一致性事务的速率超过某个限制,则所有请求都可能会减慢,即使它们是独立的。
在过去,当确实存在共享总线时,在某些情况下可能存在部分“阻止世界”行为。例如
成本非常高,因为线路将在上述两个核心之间持续乒乓(在所述过程结束时,只需反转C1和C2的角色并重新启动)。具体细节因CPU甚至平台而异(例如,2插槽配置将大大改变这种行为),但基本上可能会看到每次写入10秒的惩罚,而不是每个周期1次写入的非共享输出。 你可以在答案中找到一些具体的数字 this question 它涵盖了“同一物理核上的两个线程”和“独立核”的情况。 如果您想了解有关特定性能场景的更多详细信息,您可能应该问一个单独的特定问题,列出您感兴趣的特定行为。 1. MESI的变体通常会引入新的状态,例如 MOESI 或中的“转发”状态 MESIF . 其思想通常是使某些转换或使用模式比普通MESI协议更有效,但基本思想基本相同。 |
![]() |
Zephyr · 虚拟索引物理标记缓存同义词 7 年前 |
![]() |
Uchia Itachi · VIPT缓存:TLB和缓存之间的连接? 7 年前 |
![]() |
awdz9nld · 文件备份内存映射的CPU缓存行为/策略? 12 年前 |