Intel 64 和 IA-32 上的 MESI 有何意义

2024-05-09

  • MESI 的要点是保留共享内存系统的概念。
  • 然而,对于存储缓冲区,事情就变得复杂了:
  • 一旦数据到达 MESI 实现的缓存,下游内存就会保持一致。
  • 然而,在此之前,每个核心可能对内存位置 X 中的内容存在分歧,具体取决于每个核心的本地存储缓冲区中的内容。
  • 因此,从每个核心的角度来看,内存的状态似乎是不同的——它是不连贯的。
  • 那么,为什么我们要“部分地”强制执行与 MESI 的一致性呢?

Edit:在进一步缩小真正让我困惑的内容之后,进行了实质性的编辑。我试图保持问题的一般概念不变,以保留收到的优秀答案的相关性。


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

The result of that interaction is the architected strong memory model that x86 provides, with only limited re-ordering. Without coherent caches, you couldn't reasonably implement this model at all, or almost any model that was anything other than completely weak1.

Your question seems to embed the assumption that there are only possible states "coherent" and "everything every else". Also, there is some mixing of the ideas of cache coherency (which mostly deals with the caches specifically, and is mostly a hidden detail), and the memory consistency model which is architecturally defined and will be implemented by each architecture2. Wikipedia explains https://en.wikipedia.org/wiki/Cache_coherence that one difference between cache coherency and memory consistency is that the rules for the former applies only to one location at a time, whereas consistency rules apply across locations. In practice, the more important distinction is that the memory consistency model is the only architecturally documented one.

Briefly, Intel (and AMD likewise) define a specific memory consistency model, x86-TSO3 https://www.cl.cam.ac.uk/~pes20/weakmemory/cacm.pdf - which is relatively strong as far as memory models go, but is still weaker than sequential consistency https://en.wikipedia.org/wiki/Sequential_consistency. The primary behaviors weakened compared to sequential consistency are:

  • 较晚的负载可以通过较早的商店。
  • 该存储可以以与总存储顺序不同的顺序看到,但只能由执行其中一个存储的核心看到。

订购至实施这种记忆模型,各个部分必须按规则发挥才能实现它。在所有最新的 x86 上,这意味着有序的加载和存储缓冲区,从而避免不允许的重新排序。使用存储缓冲区会导致上述两种重新排序:如果不允许这些重新排序,实现将受到很大限制,并且可能会慢得多。实际上,这也意味着完全一致的数据缓存,因为如果没有它,许多保证(例如,没有加载-加载重新排序)将很难实现。

总结一下:

  • 内存一致性与缓存一致性不同:前者是有文档记录的,并且构成编程模型的一部分。
  • 在实践中,x86 实现有完全一致的缓存,这有助于他们实现 x86-TSO 内存模型,该模型相当强大,但弱于顺序一致性。
  • Finally, perhaps the answer you were looking for, in different words: a memory model weaker than sequential consistency is still very useful since you can program against it, and in the case you need sequential consistency for some particular operations(s) you insert the right memory barriers4.
  • 如果您针对语言提供的内存模型进行编程,例如Java's https://en.wikipedia.org/wiki/Java_memory_model or C++11's http://en.cppreference.com/w/cpp/language/memory_model您无需担心硬件细节,而不必担心语言内存模型,编译器会插入将语言内存模型语义与硬件匹配所需的障碍。硬件模型越强大,所需的障碍就越少。

1 If your memory model was completely weak, i.e., not really placing any restrictions on cross-core reordering, I suppose you could implement it directly on a non-cache coherent system in a cheap way for normal operations, but then memory barriers potentially become very expensive since they would need to flush a potentially large part of the local private cache.

2 Various chips may implement in differently internally, and in particular some chips may implement stronger semantics than the model (i.e., some allowed re-orderings can never be observed), but absent bugs none will implement a weaker one.

3 This is the name given to it in that paper, which I used because Intel themselves doesn't give it a name, and the paper is a more formal definition than the one Intel gives a less formal model as a series of litmus tests.

4 It practice on x86 you usually use locked instructions (using the lock prefix) rather than separate barriers, although standalone barriers exist also. Here's I'll just use the term barries to refer to both standalone barriers and the barrier semantics embedded into locked instructions.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Intel 64 和 IA-32 上的 MESI 有何意义 的相关文章

  • 与通道相比,sync.WaitGroup 的优势是什么?

    我正在开发一个并发 Go 库 我偶然发现了 goroutine 之间两种不同的同步模式 其结果相似 等待组 https play golang org p ZYPLlcp16TZ package main import fmt sync t
  • 具有独特矩阵转置问题的 2D 分块

    我有类型的复杂值数据struct complex double real 0 0 double imag 0 0 以 3 阶张量的形式组织 底层容器具有与内存页边界对齐的连续内存布局 The natural slicing directio
  • PAE(物理地址扩展)如何实现大于4GB的地址空间?

    维基百科文章的摘录物理地址扩展 http en wikipedia org wiki Physical Address Extension x86 处理器硬件架构通过用于选择附加内存的附加地址线进行了增强 因此物理地址大小从 32 位增加到
  • D 并发写入缓冲区

    假设您有一个大小为 N 的缓冲区 必须将其设置为确定的值 例如零或其他值 缓冲区中的此值设置分为 M 个线程 每个线程处理缓冲区的 N M 个元素 缓冲区不能immutable 因为我们改变了值 消息传递也不起作用 因为禁止传递 ref 或
  • long double(GCC 特定)和 __float128

    我正在寻找有关的详细信息long double and float128在 GCC x86 中 更多是出于好奇而不是因为实际问题 可能很少有人需要这些 我只是有史以来第一次 truly需要一个double 但我想知道你的工具箱里有什么以及它
  • 在S3客户端android中制作私有图像的ImageGallery

    我正在尝试在 Android 应用程序中创建 S3 Bucket 的 imageGallery 我的图像是私人的 所以我不会为每个图像提供任何特定的链接 对于此类私人图像 亚马逊有一个链接生成器 s3Client generatePresi
  • 在 x86 程序集中打印寄存器值的简单方法

    我需要在 8086 Assembly 中编写一个程序 接收来自用户的数据 进行一些数学计算并在屏幕上打印答案 我已经编写了程序的所有部分并且一切正常 但我不知道如何打印号码显示到屏幕上 在我所有计算结束时 答案是 AX 它被视为无符号 16
  • 让浏览器缓存我的动态 PHP 样式表

    我想在 PHP 文件 styles php 中创建一个样式表 以便样式表变得动态 具体取决于请求的用户 对于每个单独的用户来说 样式表是不变的 因此应该缓存在他的客户端浏览器上 我读过 您可以通过设置内容类型和缓存控制等标头来实现此目的 但
  • 寻找简单的Java内存缓存[关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找一个简单的Java内存缓存 它具有良好的并发性 因此LinkedHashMap不够好 并且可以
  • 难以理解汇编命令“加载有效地址”[重复]

    这个问题在这里已经有答案了 可能的重复 LEA 指令的目的是什么 https stackoverflow com questions 1658294 whats the purpose of the lea instruction LEA指
  • 对将英特尔傲腾 DC SSD 用作 IMDT 的额外 RAM 感到困惑吗? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我对英特尔傲腾 DC 有点困惑 我希望我的 Optane DC 能够同时充当 DRAM 和存储 一方面 我了解到只有 英特尔傲腾 DC 持
  • cudaDeviceScheduleBlockingSync 和 cudaDeviceScheduleYield 之间有什么区别?

    正如这里所说 如何减少 CUDA 同步延迟 延迟 https stackoverflow com questions 11953722 how to reduce cuda synchronize latency delay 等待设备结果有
  • 如何让BackgroundWorker返回一个对象

    我需要做RunWorkerAsync 返回一个List
  • 无法禁用 jQuery 缓存

    Update 我发现这一定是缓存问题 但我无法关闭缓存 这是我更改后的脚本
  • ArrayDeque 和 LinkedBlockingDeque

    只是想知道为什么他们做了一个LinkedBlockingDeque而同一个非并发对应物是ArrayDeque它基于可调整大小的数组 LinkedBlockingQueue使用一组节点 例如LinkedList 尽管没有实施List 我知道可
  • 如何读取 UDP 连接直至超时?

    我需要读取 UDP 流量 直到超时 我可以通过在 UDPConn 上调用 SetDeadline 并循环直到出现 I O 超时错误来做到这一点 但这看起来很黑客 基于错误条件的流量控制 下面的代码片段看起来更正确 但并没有终止 在生产中 这
  • 如何告诉 OkHttpClient 忽略缓存并强制从服务器刷新?

    在我的 Android 应用程序中 我将 Retrofit 与 OkHttpClient 结合使用 并启用缓存来访问某些 API 我们的一些 API 有时会返回空数据 我们在应用程序中提供了一个 刷新 按钮 供客户端从特定 API 重新加载
  • Java HashSet 是线程安全的只读吗?

    如果我通过 Collections unmodifyingSet 运行 HashSet 实例后 它是线程安全的吗 我问这个是因为 Set 文档声明它不是 但我只是执行读取操作 来自 Javadoc 请注意 此实现不是同步的 如果多个线程同时
  • 如果默认禁用 A20 线,如何在 0xFFFFFFF0 处访问 BIOS ROM?

    我正在阅读有关 A20 线的信息http wiki osdev org A20 Line http wiki osdev org A20 Line 这似乎表明 A20 线默认被禁用 在Pentium上 如果硬复位后立即输出的地址为0xFFF
  • 如何在 AVX/AVX2 中递增向量

    我想使用内在函数来增加 SIMD 向量的元素 最简单的方法似乎是为每个元素加 1 如下所示 note vec inc之前已设置为1 vec mm256 add epi16 vec vec inc 但是是否有任何特殊指令来增加向量 类似于in

随机推荐