caching - MESI在Intel 64和IA-32上的意义是什么

标签 caching concurrency x86 cpu-architecture mesi

  • MESI的重点是保留共享内存系统的概念。
  • 但是,有了存储缓冲区,事情变得很复杂:
  • 一旦数据命中了MESI实现缓存,内存就在下游。
  • 但是,在此上游,每个内核可能对内存位置X中的内容有所不同,这取决于每个内核的本地存储缓冲区中的内容。
  • 这样,从每个内核的角度来看,内存的状态似乎是不同的-它不是一致的。
  • 那么,为什么我们要“部分地”与MESI加强一致性呢?

  • 编辑:在进一步缩小真正令我困惑的地方之后,进行了实质性的编辑。我试图使问题的一般概念保持不变,以保持收到的好答案的相关性。

    最佳答案

    x86上的MESI点与几乎所有多核/ CPU系统上的点相同:增强缓存一致性。 x86上的等式的缓存一致性部分没有使用“部分一致性”:缓存是完全一致性的。因此,可能的重新排序是相关的缓存系统以及与核心本地组件(例如加载/存储子系统(尤其是存储缓冲区)和其他乱序机器)的交互作用的结果。

    交互的结果是x86提供的经过架构的强大内存模型,仅进行了有限的重新排序。没有连贯的缓存,您将根本无法合理地实现此模型,或者几乎无法实现除完全弱化之外的任何模型。

    您的问题似乎嵌入了这样的假设,即只有可能的状态是“连贯的”和“其他所有状态”。此外,还有一些缓存一致性的思想(主要是专门处理缓存,并且大部分是隐藏的细节)与内存一致性模型混合在一起,后者由体系结构定义并且将由每个体系结构实现2。 Wikipedia explains指出,缓存一致性和内存一致性之间的一个区别是,前者的规则一次仅适用于一个位置,而一致性规则适用于各个位置。实际上,更重要的区别是内存一致性模型是唯一在架构上记录的模型。

    简而言之,英特尔(和AMD同样)定义了一个特定的内存一致性模型x86-TSO3-就内存模型而言,它相对较强,但仍比sequential consistency弱。与顺序一致性相比,被削弱的主要行为是:

  • 以后的加载可以传递以前的存储。
  • 可以按与总商店顺序不同的顺序查看商店,但是只能由执行其中一个商店的核心看到。

  • 为了使实现这个内存模型,必须通过规则的各个部分来实现它。在所有最新的x86上,这意味着有序的加载和存储缓冲区,避免了不允许的重新排序。使用存储缓冲区会导致上面提到的两个重新排序:如果不允许这些重新排序,则实现将非常受限制,并且可能会慢得多。实际上,这也意味着完全一致的数据高速缓存,因为如果没有这种保证,许多保证(例如,没有负载-负载重新排序)将很难实现。

    总结一下:
  • 内存一致性不同于高速缓存一致性:前者是已记录的内容,并构成编程模型的一部分。
  • 实际上,x86实现具有完全一致的缓存,这可以帮助他们实现x86-TSO内存模型,该模型相当强大,但比顺序一致性弱。
  • 最后,也许您正在寻找答案,换句话来说:弱于顺序一致性的内存模型仍然非常有用,因为您可以针对它进行编程,并且在某些情况下,您需要针对某些特定操作插入顺序一致性正确的记忆障碍4。
  • 如果您针对语言提供的内存模型(例如Java'sC++11's)进行编程,则无需担心硬件规格,而不必担心语言内存模型,并且编译器会插入匹配语言内存模型语义所需的障碍。硬件之一。硬件模型越强大,所需的障碍就越少。


  • 1如果您的内存模型是完全弱的,即没有对跨核重新排序真正施加任何限制,我想您可以以便宜的方式直接在非缓存一致性系统上直接实现它,以实现正常操作,但是内存障碍可能会变成这非常昂贵,因为它们将需要刷新本地私有(private)缓存的很大一部分。

    2各种芯片可能会在内部以不同的方式实现,特别是某些芯片可能会实现比模型更强的语义(即,永远不会观察到某些允许的重新排序),但是没有错误的bug都不会实现较弱的错误。

    3这是该论文中给它命名的名称,我之所以使用它是因为Intel自己没有给它起名字,并且该论文是一个更正式的定义,而不是Intel通过一系列石蕊测试给出的非正式模型。

    4在x86上,您通常使用锁定指令(使用lock前缀)而不是单独的障碍,尽管也存在独立的障碍。在这里,我将仅使用术语Barries来指代独立的屏障和嵌入在锁定指令中的屏障语义。

    关于caching - MESI在Intel 64和IA-32上的意义是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49843709/

    相关文章:

    python - 使用自己的 python 调试器获取系统调用时遇到问题

    interrupt - 静态定义的 IDT

    c# - 如何检查 System.Runtime.Caching.ObjectCache 中的缓存策略?

    django - 如何手动清除/更新 Django 中的缓存 View

    java - 是否可以从两个不同的 Servlet 同时访问同一个数据库?

    objective-c - NSOperationQueue 有储备能力吗?

    caching - magento https + IE8 提示问题

    c++ - 可以使用缓存制作 QML 应用程序 "offline capable"吗?

    .net - SwitchToThread/Thread.Yield 与 Thread.Sleep(0) 与 Thread.Sleep(1)

    assembly - 有什么可以防止汇编中的堆栈溢出吗?