x86 上的 MESI 的意义与几乎任何多核/CPU 系统上的相同:强制缓存一致性。x86 上等式的缓存一致性部分没有使用“部分一致性”:缓存是完全一致的。因此,可能的重新排序是连贯缓存系统和与核心本地组件(例如加载/存储子系统(尤其是存储缓冲区)和其他无序机制)交互的结果。
这种交互的结果是 x86 提供的架构强大的内存模型,只有有限的重新排序。如果没有一致的缓存,您根本无法合理地实现这个模型,或者几乎任何模型都不是完全弱1。
你的问题似乎嵌入了这样一个假设,即只有可能的状态“连贯”和“其他一切”。此外,缓存一致性(主要处理缓存,并且主要是隐藏的细节)的想法与架构定义并将由每个架构2实现的内存一致性模型有一些混合。维基百科解释说,缓存一致性和内存一致性之间的一个区别是前者的规则一次只适用于一个位置,而一致性规则适用于不同的位置。在实践中,更重要的区别是内存一致性模型是唯一在架构上记录的模型。
简而言之,英特尔(和 AMD)定义了一个特定的内存一致性模型,x86-TSO 3 - 就内存模型而言,它相对强大,但仍然比顺序一致性弱。与顺序一致性相比,削弱的主要行为是:
- 以后的负载可以通过较早的商店。
- 可以以与商店总订单不同的顺序查看该商店,但只能通过执行其中一个商店的核心来查看。
为了实现这个内存模型,各个部分必须按照规则来实现它。在所有最近的 x86 上,这意味着有序的加载和存储缓冲区,这避免了不允许的重新排序。使用存储缓冲区会导致上面提到的两个重新排序:如果不允许这些,实现将受到很大限制并且可能会慢得多。在实践中,它还意味着完全一致的数据缓存,因为如果没有它,许多保证(例如,没有加载-加载重新排序)将很难实现。
总结一下:
- 内存一致性不同于缓存一致性:前者是记录在案的内容,并构成编程模型的一部分。
- 在实践中,x86 实现具有完全一致的缓存,这有助于他们实现其 x86-TSO 内存模型,该模型相当强大,但比顺序一致性弱。
- 最后,也许您正在寻找的答案,换句话说:弱于顺序一致性的内存模型仍然非常有用,因为您可以针对它进行编程,并且在您需要某些特定操作的顺序一致性的情况下,您插入正确的记忆障碍4。
- 如果您针对语言提供的内存模型(例如Java或C++11)进行编程,则无需担心硬件细节,而不必担心语言内存模型,并且编译器会插入匹配语言内存模型所需的障碍语义到硬件之一。硬件模型越强大,所需的障碍就越少。
1如果您的内存模型完全弱,即没有真正对跨核重新排序设置任何限制,我想您可以直接在非缓存一致系统上以廉价的方式实现正常操作,但是内存障碍可能会变成非常昂贵,因为他们需要刷新可能很大一部分本地私有缓存。
2各种芯片的内部实现方式可能不同,特别是一些芯片可能实现比模型更强的语义(即,一些允许的重新排序永远不会被观察到),但没有错误不会实现更弱的。
3这是那篇论文中给它的名称,我之所以使用这个名称,是因为英特尔自己没有给它命名,而且这篇论文是一个比英特尔给出的不太正式的模型作为一系列试金石测试的更正式的定义。
4它在 x86 上练习,您通常使用锁定指令(使用lock
前缀)而不是单独的屏障,尽管也存在独立的屏障。这里我将只使用术语barries来指代独立屏障和嵌入到锁定指令中的屏障语义。