assembly - MESI 协议(protocol)是否足够,还是仍然需要内存屏障? (英特尔 CPU)

标签 assembly x86 cpu cpu-architecture cpu-cache

我发现了一个英特尔文档,其中指出使用字符串(不是 std::string ,而是汇编字符串指令)时需要内存屏障,以防止 CPU 重新排序它们。

但是,当两个线程(在两个不同的内核上)访问同一个内存时,是否也需要内存屏障?我想到的场景是其中一个不“拥有”高速缓存行的 CPU 写入此内存,而核心写入其存储缓冲区(而不是其高速缓存)。需要一个内存屏障将值从存储缓冲区刷新到缓存,所以其他核心可以获得这个值?

我不确定在英特尔上,MESI 协议(protocol)是否可以处理这个问题?

(我试图(糟糕地)解释上面的内容在下面的论文中得到了更好的描述,第 6-12 页):

http://www.puppetmastertrading.com/images/hwViewForSwHackers.pdf

上面的论文非常笼统,我不确定英特尔 CPU 是如何处理这个问题的。

最佳答案

MESI 协议(protocol)适用于缓存,存储缓冲本质上是预缓存,这意味着它是一个尚未向外界“发布”的存储,其同步点尚未确定。

您还需要记住,缓存一致性仅保证写入不会发生在缓存行的陈旧副本上并且不会在此过程中丢失。此类协议(protocol)的唯一保证是隐藏您拥有具有复制值的缓存的事实(本身就是性能优化),并向程序员/操作系统暴露单级平面物理内存的错觉。

就其本身而言,不能保证从多个内核读取和写入的顺序,为此,您需要使用 ISA 提供的其他构造(如锁、栅栏和依赖内存排序规则)来管理代码。

您描述的情况是不可能的,因为它破坏了第一部分 - 不拥有线路的核心无法写入内存,因为它会错过拥有线路的核心中的更新数据(如果存在)。在 MESI 协议(protocol)下会发生的情况是,写入将被缓冲一段时间,当轮到它发出时 - 它会发送所有权请求,这将使其他内核中该行的所有副本无效(如果有一个修改后的副本),并获取更新的数据。只有这样,编写器核心才能修改该行并将其标记为已修改。

但是,如果 2 个内核同时写入同一行,MESI 协议(protocol)仅保证这些写入将有一些顺序,而不是您可能想要的特定顺序。更糟糕的是 - 如果每个核心都写了几行,并且您希望这些写操作具有原子性,MESI 不保证这一点。您需要主动添加互斥锁或某种屏障,以强制硬件以您想要的方式执行写入。

关于assembly - MESI 协议(protocol)是否足够,还是仍然需要内存屏障? (英特尔 CPU),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27522190/

相关文章:

linux - 如何通过查看堆栈值生成回溯?

assembly - 可以在同一代码路径中混合传统 SSE 编码指令和 VEX 编码指令吗?

c - 动态电压和频率缩放 API

c++ - 从我的 C/C++ 代码中获取等效的汇编代码 - x86 和 ARM

linux - 如何编译 Intel x86 汇编代码以获取十六进制转储?

arrays - 汇编器数组最大元素搜索

assembly - 38 "D"D 位中的 6's "代表什么?

c - X86 32b 汇编 - 使用 atoll

gcc - 如何使用 GCC 4.4.7-17 禁用 bmi 指令

caching - 缓存内存: What is the difference between a tag and an index?