x86 CPU 有多少条内存屏障指令?

2023-11-22

我发现 x86 CPU 有以下内存屏障指令:mfence, lfence, and sfence.

x86 CPU 是否只有这三个内存屏障指令,还是还有更多?


sfence(上交所1)和mfence / lfence(SSE2) 是唯一以其内存栅栏/屏障功能命名的指令。除非您使用 NT 存储和/或 WC 内存(以及 NT 从 WC 加载),否则仅mfence内存排序需要。

(注意lfence在Intel CPU上也是乱序执行的障碍,因此它可以序列化rdtsc,并且对于 Spectre 缓解很有用,可以防止推测执行。在AMD上,必须设置MSR,否则lfence基本上是一个nop(4/周期吞吐量)。该 MSR 是通过 Spectre 缓解微代码更新引入的,通常由更新的内核设置。)


locked 指令如lock add [mem], eax也是满内存屏障. lock xchg 与 mfence 具有相同的行为吗?。 (虽然可能不如mfence用于从 WC 内存订购 NT 加载:锁定指令是否在弱顺序访问之间提供了屏障?). xchg [mem], reg有一个隐含的lock前缀,所以它也是一个障碍。

在我对 Skylake 的测试中, locked 指令会使用此代码阻止 NT 存储与常规存储的重新排序https://godbolt.org/g/7Q9xgz.

xchg似乎是进行 seq-cst 存储的好方法,特别是在 Intel 硬件上,例如天湖在哪里mfence还阻止纯 ALU 指令的乱序执行, like lfence: See 这个答案的底部.

AMD 还建议使用xchg或其他锁定指令代替mfence. (mfence在 AMD 手册中记录为在 AND 上进行序列化,因此它总是会受到阻塞 OoO exec 的惩罚)。


对于没有 SSE 的 32 位目标上的顺序一致性存储或完全屏障,编译器通常使用lock or [esp], 0或其他无操作锁定指令just为了记忆屏障效应。就是这样g++7.3 -O3 -m32 -mno-sse does为了std::atomic_thread_fence(std::memory_order_seq_cst);.

但无论如何,都没有mfence nor locked ins 是建筑上的定义为 Intel 上的序列化,无论某些 CPU 上的实现细节如何。


完整的序列化指令,例如cpuid也是满内存屏障,排空存储缓冲区并刷新管道。lock xchg 与 mfence 具有相同的行为吗?Intel手册中有相关引用。

在 Intel 处理器上,以下是架构序列化指令(来自:https://xem.github.io/minix86/manual/intel-x86-and-64-manual-vol3/o_fe12b1e2a880e0ce-273.html):

  • 特权序列化指令— INVD、INVEPT、INVLPG、INVVPID、LGDT、LIDT、LLDT、LTR、MOV 到控制寄存器、MOV(到调试寄存器)、WBINVD 和 WRMSR。

    例外情况:MOV CR8没有序列化。WRMSRIA32_TSC_DEADLINE MSR(MSR 索引 6E0H)和 X2APIC MSR(MSR 索引 802H 到 83FH)未序列化。

  • Non-privileged serializing instructions — CPUID, IRET1, and RSM

在 AMD 处理器上,以下是架构上的序列化指令:

  • 特权序列化指令— INVD、INVLPG、LGDT、LIDT、LLDT、LTR、MOV 到控制寄存器、MOV(到调试寄存器)、WBINVD、WRMSR 和 SWAPGS。

  • 非特权序列化指令— MFENCE、CPUID、IRET 和 RSM

Intel 处理器上的术语“[完全]序列化指令”与 AMD 处理器上的含义完全相同,除了一个区别:高速缓存行刷新操作CLFLUSH(但不是CLFLUSHOPT)仅针对后续指令进行排序MFENCE在 AMD 处理器上。


in / out(以及它们的字符串复制版本ins and outs)是完整的内存屏障,并且也是部分序列化(例如lfence)。文档称,它们会延迟执行下一条指令,直到 I/O 事务的“数据阶段”之后。


脚注:

(1) 根据BJ137(Sandy Bridge)、HSD152(Haswell)、BDM103(Broadwell):

问题:IRET 指令导致任务切换 从嵌套任务返回不会序列化处理器 (与软件开发人员手册第 3 卷标题为 “序列化说明”)。

含义:依赖序列化的软件 任务切换期间 IRET 的属性可能不会表现为 预期的。英特尔尚未发现此错误会影响 任何商业软件的操作。

解决方法:未确定。软件可以执行 MFENCE 如果序列化,则紧接在 IRET 指令之前的指令 是需要的。

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

x86 CPU 有多少条内存屏障指令? 的相关文章

随机推荐

  • PDO - 获取当前插入的ID

    query INSERT INTO news VALUES NULL param1 param2 stmt pdo gt prepare query params array param1 gt p title param2 gt p bo
  • 如何在指定节点TOC(.NET)上打开CHM文件

    您好 我需要在 NET 应用程序中实现上下文帮助 我有 chm 文件 我正在寻找在标准查看器中打开它的可能性 并突出显示目录 或索引条目 所需的主题 知道如何存档吗 EDIT 也许用于打开 CHM 文件的 MS 应用程序有一些允许存档的命令
  • 使用 Pylint 显示错误和警告

    所以我开始使用 Pylint 但由于我使用制表符而不是空格 它给了我警告 也因为一些方法来自基类 它们也是 GalleryUi 的实例 没有 setModel 成员 而它有 QAbstractTableModel作为基类 那么我如何设置 P
  • Solidity:如何将 bytes32 表示为字符串

    这在其他语言中可能很简单 但我不知道如何在 Solidity 中做到这一点 我有一个bytes32像这样0x05416460deb76d57af601be17e777b93592d8d4d4a4096c57876a91c84f4a712 I
  • 如何使用 Eclipse 编译 32 位

    我目前正在我的 64 位 Ubuntu 电脑上用 C 编写一个小程序 默认情况下 eclipse 会编译 64 位架构的程序 因为我想在我的服务器上使用我的小程序 仍然是 32 位 所以我需要能够编译 32 位程序 我怎样才能在日食中做到这
  • 从其他视图拖动时检测视图上的触摸事件

    如果用户触摸视图 A 并拖动到视图 B 的底部 如何检测触摸事件 我想检测视图 B 中的触摸事件 我在视图 B 中添加了触摸监听器 但如果用户最初触摸 A 并将其拖动到 B 上 则不会收到事件 您可以使用下面的代码来实现您的请求 测试视图边
  • 如何在 Pygame 中截取屏幕的特定部分

    有没有办法可以截取 pygame 窗口右半部分的屏幕截图 我正在使用 pygame 制作游戏 我需要拍摄屏幕快照 但不是整个屏幕 只是右半部分 我知道 pygame image save screen screenshot jpg 但这将包
  • 计算地理邻近度的公式

    我需要在我的应用程序中实现地理邻近搜索 但我对使用的正确公式感到非常困惑 经过在网络和 StackOverflow 中的一些搜索 我发现解决方案是 Use the 半正矢公式 Use the Great Circle Distance Fo
  • .net 中的转换:本机 Utf-8 <-> 托管字符串

    我创建了这两种方法来将本机 utf 8 字符串 char 转换为托管字符串 反之亦然 下面的代码完成了这个工作 public IntPtr NativeUtf8FromString string managedString byte buf
  • 找不到版本 GLIBCXX_3.4.11(buildW.mexglx 需要)

    我正在尝试通过 matlab 编译 C ubuntu 项目here 当我在使用 make 命令编译后尝试使用它时 出现以下错误 Invalid MEX file fashionista v0 2 lib bsr buildW mexglx
  • 从输入迭代器创建 C++ std::string 的性能

    我正在做一些非常简单的事情 将整个文本文件从磁盘放入std string 我当前的代码基本上是这样做的 std ifstream f filename return std string std istreambuf iterator
  • 未找到 Android SSL 连接的信任锚

    我正在尝试连接到运行 godaddy 256 位 SSL 证书的 IIS6 机器 但收到错误 java security cert CertPathValidatorException Trust anchor for certificat
  • 使用 PHP 创建 ping 正常运行时间服务

    我有一台可以使用 PHP 的服务器和一个可以从 Internet ping 通的路由器 我想编写一个 PHP 脚本 每 5 分钟向路由器发送一次 ping 结果如下 如果 ping 成功 则不会发生任何事情 如果 ping 失败 则会等待几
  • 当另一个视图控制器显示在 UIPresentationController 之上时,UIPresentationController 会更改大小

    我正在使用 UIPresentationController 展示一个模式视图控制器 我使用以下方法将presentedView 的框架设置为小于containView 的边界 override func frameOfPresentedV
  • mutex.Lock() 如何知道要锁定哪些变量?

    我是个新手 所以请温柔一点 所以我已经在我的一些代码中使用互斥体几周了 我理解其背后的概念 锁定对特定资源的访问 与其交互 读或写 然后再次为其他资源解锁 我使用的互斥体代码主要是复制粘贴调整 代码运行了 但我仍在尝试了解它的内部工作原理
  • 按日期对文件排序

    我在网上找到了这个目录检查代码并稍微修改了一下 这样它就会打印出添加的文件 有一个浮标时不时地向我发送读数 但有时连接会丢失 而不是一个文件 而是发送多个文件 我需要该程序按创建日期对它们进行排序 有没有办法做到这一点 import os
  • 为什么 Java 和 C# 有位移运算符?

    整数乘法 暂时忘记除法 之间的差异是否仍然有利于移位 如果是的话 差异有多大 它看起来只是一个低级优化 即使您想要它 在大多数情况下 C Java 字节码编译器或 jit 不应该捕获它吗 注意 我测试了 C 的编译输出 使用 gmcs Mo
  • 设置 UITextField 的最大字符长度

    如何设置一个文件的最大字符数UITextField当我加载一个iPhone SDK时UIView 虽然UITextField类没有最大长度属性 通过设置文本字段的值来获得此功能相对简单delegate并实现以下委托方法 Objective
  • 在运行时,如何测试属性是否是只读的?

    我正在自动生成代码 根据配置 文本框 dateTimePickers 等 创建 winform 对话框 这些对话框上的控件是从保存的数据集填充的 需要设置和获取各种控制对象 自定义或其他 的属性 Upon opening of form p
  • x86 CPU 有多少条内存屏障指令?

    我发现 x86 CPU 有以下内存屏障指令 mfence lfence and sfence x86 CPU 是否只有这三个内存屏障指令 还是还有更多 sfence 上交所1 和mfence lfence SSE2 是唯一以其内存栅栏 屏障