x86 上哪个写屏障更好:lock+addl 或 xchgl?

2023-11-25

Linux 内核使用lock; addl $0,0(%%esp)作为写屏障,而 RE2 库使用xchgl (%0),%0作为写屏障。有什么区别,哪个更好?

x86 也需要读屏障指令吗? RE2 将其读屏障函数定义为 x86 上的无操作,而 Linux 将其定义为lfence或无操作取决于 SSE2 是否可用。什么时候lfence必需的?


引用 IA32 手册(第 3A 卷,第 8.2 章:内存排序):

在定义为可回写缓存的内存区域的单处理器系统中,内存排序模型遵循以下原则 [..]

  • 读取不会与其他读取重新排序
  • 写入不会与较旧的读取重新排序
  • Writes to memory are not reordered with other writes, with the exception of
    • 写入执行与CLFLUSH操作说明
    • 使用非临时移动指令执行流式存储(写入)([此处的指令列表])
    • 字符串操作(参见第 8.2.4.1 节)
  • 读取可以与对不同位置的较旧写入进行重新排序,但不能与对同一位置的较旧写入进行重新排序。
  • 读取或写入无法使用 I/O 指令、锁定指令或序列化指令重新排序
  • 读取无法通过LFENCE and MFENCE指示
  • 写入无法通过SFENCE and MFENCE指示

注意:上面的“在单处理器系统中”有点误导。相同的规则分别适用于每个(逻辑)处理器;然后,手册继续描述多个处理器之间的附加排序规则。与这个问题有关的唯一一点是

  • 锁定指令具有总顺序。

简而言之,只要您写入回写内存(只要您不是驱动程序或图形程序员,您就会看到所有内存),大多数 x86 指令几乎顺序一致 - 唯一的重新排序x86 CPU 可以执行重新排序稍后(独立)读取以在写入之前执行。关于写屏障的主要问题是它们有一个lock前缀(隐式或显式),它禁止所有重新排序并确保多处理器系统中的所有处理器以相同的顺序看到操作。

此外,在回写存储器中,读取永远不会重新排序,因此不需要读取屏障。最新的 x86 处理器对于流存储和写组合内存(通常用于映射图形内存)具有较弱的内存一致性模型。这就是各种fence指令开始发挥作用;它们对于任何其他内存类型都不是必需的,但 Linux 内核中的某些驱动程序确实处理写组合内存,因此它们只是以这种方式定义其读屏障。每个存储器类型的订购模型列表位于第 11.3.1 卷第 11.3.1 节中。 IA-32 手册的 3A。简短版本:直写式、回写式和写保护式允许推测性读取(遵循上面详述的规则),不可缓存和强不可缓存内存具有强大的排序保证(没有处理器重新排序,读/写立即执行,用于 MMIO )和写入组合内存的排序较弱(即需要栅栏的宽松排序规则)。

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

x86 上哪个写屏障更好:lock+addl 或 xchgl? 的相关文章

  • 无法识别的仿真模式:MinGW32 上的 elf_i386

    我正在尝试制作内核 但无法链接C与程序集一起输出 这ld 我收到错误 无法识别的仿真模式 elf i386 我正在使用 Windows 10 专业版以及 MinGW32 和 MSYS 我正在使用的代码 link ld link ld OUT
  • 使用 Gas 生成与位置无关的代码 (-fPIC)

    我尝试在 x86 64 上创建共享库但失败 问题归结为以下代码 请不要介意 它没有多大意义 section data newline ascii n section text globl write newline type write n
  • 如何在 GCC C++ 中编写多行内联汇编代码?

    这看起来不太友好 asm command 1 command 2 command 3 我真的必须在每一行加上双引号吗 另外 由于多行字符串文字在 GCC 中不起作用 我也无法欺骗它 我总是在互联网上找到一些例子 该人手动插入制表符和换行符而
  • 调用可以是 cdecl 或 stdcall 的函数

    我需要编写调用外部函数的代码 该函数可以是 32 位 Windows 应用程序中的 stdcall 调用或 cdecl 我的代码 调用者 无法提前知道其中的哪一个 现在 如果我尝试从定义为 stdcall 的调用站点调用 cdecl 函数
  • _mm_max_ss 在 clang 和 gcc 之间有不同的行为

    我正在尝试使用 clang 和 gcc 交叉编译一个项目 但在使用时发现一些奇怪的差异 mm max ss e g m128 a mm set ss std numeric limits
  • 将 C 代码转换为 x86-64 汇编

    我正在尝试将 C 代码转换为 x86 64 我的目标是反转链表 传入的两个参数是 head ptr 和 offset to 以获取指针字段的地址 即指向列表中下一个节点的指针 据我了解 head ptr是通过rdi寄存器传入的 offset
  • 当 mov 指令导致页面错误并且在 x86 上禁用中断时会发生什么?

    我最近在自定义 Linux 内核 2 6 31 5 x86 驱动程序中遇到一个问题 其中 copy to user 会定期不将任何字节复制到用户空间 它将返回传递给它的字节数 表明它没有复制任何内容 经过代码检查 我们发现代码在调用 cop
  • Polygot 包含 nasm/yasm 和 C 的文件

    我有一堆幻数 我想将它们包含在由 nasm 或 yasm 编译的 C 程序和汇编文件中 在纯 C 语言中 该文件看起来像是一系列定义 例如 define BLESS 55378008 define ANSWER 42 在 nasm 或 ya
  • ICC 中的 -O3 会扰乱内在函数,使用 -O1 或 -O2 或相应的手动汇编即可

    这是后续这个问题 http stackoverflow com questions 49791664 o2 in icc messes up assembler fine with o1 in icc and all optimizatio
  • 从c调用汇编函数

    我试图从 c 调用汇编函数 但我不断收到错误 text globl integrate type integrate function integrate push ebp mov esp ebp mov 0 edi start loop
  • 68000 汇编语言 - CMPI.B

    What are the contents of the CCR and D3 after the following instructions sequence executes Perform the calculation by ha
  • 使用 ACPI 在 MS-DOS 中关闭计算机

    我在基于 Pentium 的计算机上运行 MS DOS 6 22 主板支持 ACPI 并且想知道是否有一个可以用来关闭计算机的汇编语言例程 或者它是否比那个更难 即主板 具体的 基本上 我想创建一个小程序来从命令行关闭计算机 这是专门为此编
  • 为什么前向引用 ADR 指令在 Thumb 代码中以偶数偏移进行汇编?

    To bx对于 Thumb 函数 需要设置地址的最低有效位 GNU 作为文档states https sourceware org binutils docs as ARM Opcodes html当地址是从一个生成时这是如何工作的adr伪
  • 为什么 LED 保持亮起而不是闪烁?

    这是使用 pic16f676 中的 TIMER0 中断使 LED 闪烁的 MPASM 代码 端口 A 的引脚 0 RA0 未切换至关闭位置 请帮忙 我是图片组装的新手 我想掌握图片 有没有高手帮我学习一下 我需要以 1 秒的间隔眨眼 代码是
  • 汇编语言程序中连续两次相乘

    我正在使用 8086 模拟器以及 DOSBOX 和 MASM 我知道当我们将 8 位与 8 位相乘时 答案将是 16 位 al 8 bit ax 当我们将 16 位与 16 位相乘时 答案将是 32 位 ax 16 bit dx ax 但如
  • movsbl指令的作用是什么? [复制]

    这个问题在这里已经有答案了 我在网上搜索过 但找不到明确的示例来理解该指令的作用 因此 如果有人可以举一个例子 这对我来说将会非常有帮助 用符号从字节扩展到长字移动 在Intel语法中 该指令的助记符是MOVSX 当变量类型为 C 时 C
  • 原子的 C++ 内存屏障

    在这方面我是个新手 谁能提供以下内存屏障之间差异的简化解释 窗户MemoryBarrier 围栏 mm mfence 内联汇编asm volatile memory 内在的 ReadWriteBarrier 如果没有简单的解释 一些好文章或
  • INT 13h 无法读取超出特定扇区的数据

    我正在为我的操作系统编写内核 在将磁盘扇区加载到内存时遇到问题 以下是从磁盘加载扇区的函数代码部分 mov ax 0x3000 mov es ax mov ax 0x0201 mov bx word ptr bp 6 bx 0x000 0x
  • 如何使 gcc 为 -fpatchable-function-entry 发出多字节 NOP?

    gcc确实有能力使用多字节用于对齐循环和函数的 NOP 然而当我尝试 fpatchable function entry option https gcc gnu org onlinedocs gcc Instrumentation Opt
  • 如何阅读英特尔操作码符号

    我正在阅读一些引用的材料Intel vol 2 SDM x86 手册 https www intel com content www us en developer articles technical intel sdm html关于汇编

随机推荐

  • 任务“:app:kaptGenerateStubsDebugKotlin”执行失败

    将 android studio 从 electricEel 更新为 Flamingo 插件后id kotlin kapt 导致错误 Execution failed for task app kaptGenerateStubsDebugK
  • 分配在堆上的对象

    每当创建任何新对象时 都会在堆上创建该对象 为每个对象分配的内存有两个附加字段 1 类型对象指针 2 同步块索引 这两个字段到底有什么用途 有人能解释一下吗 类型对象指针用于表示对象的类型 这是必需的 方法查找 vtable 检查石膏 寻找
  • HTML Purifier - 净化什么?

    我正在使用 HTML Purifier 来保护我的应用程序免受 XSS 攻击 目前 我正在净化所见即所得编辑器中的内容 因为这是唯一允许用户使用 XHTML 标记的地方 我的问题是 我是否应该在登录身份验证系统中的用户名和密码 或注册页面的
  • 在自定义编辑类型字段中添加多个输入元素

    有没有办法创建具有多个输入元素的自定义字段 我正在咨询文档创建单个输入元素非常简单 但我不太确定如何添加多个输入元素 以前有人走过这座桥吗 如果是这样 你是怎么做到的 这是一些示例代码 name Dimensions index Dimen
  • 在 BrowseFragment 中禁用行缩放/展开

    我还没有找到任何文档如何在将焦点从标题切换到 BrowseFragment 中的片段时禁用行缩放 倚背版本 24 2 0 BrowseFragment有一个功能enableMainFragmentScaling这部分解决了问题 图像现在具有
  • 如何查看是否点击同一个元素两次? jQuery

    如何检测用户是否点击同一个 div 我尝试过这个但没有成功 oldthis null var this this if oldthis this alert You clicked this last oldthis this 您无法比较
  • Laravel Auth::logout 未删除记住我的 cookie

    因此 我将会话的生命周期设置为两周 这样用户就不必多次登录或退出 然而今天我注意到一些事情 如果您注销 它会破坏您的会话 但会在您的浏览器上保留 记住我 cookie 这会导致问题 因为如果您在同一台计算机上切换帐户 8 10 次 您会收到
  • 事务中的 LAST_INSERT_ID() 可靠吗?

    我正在使用 mysql ado net C 这是我的问题 我知道 mysql 是并发的 但是我有文件数据 缩略图名称 和数据库数据 行 同步 如果我开始一笔交易 但因任何原因失败 这会是一个问题吗 如果我在两个核心上同时运行这段代码 它们会
  • 在iPhone App中如何检测设备的屏幕分辨率

    在 iPhone 应用程序中 在设备上运行App时如何检测运行App的设备的屏幕分辨率 CGRect screenBounds UIScreen mainScreen bounds 这将为您提供整个屏幕的分辨率 以点为单位 因此 iPhon
  • 异常处理模式

    这是我看到的一种常见模式 其中与异常相关的错误代码存储为静态最终整数 当创建要抛出的异常时 它是用这些代码之一以及错误消息构造的 这导致要捕获它的方法必须查看代码 然后决定操作过程 另一种选择似乎是为每个异常错误情况声明一个类 尽管相关异常
  • 在 Swing 应用程序中组织操作?

    我当前的应用程序有一个 JFrame 其中约有 15 个操作存储为 JFrame 中的字段 每个操作都是一个匿名类 其中一些非常长 将操作分解为它们自己的类 可能位于称为操作的子包中 是否很常见 如果不是 通常如何控制这种复杂性 Thank
  • 如何使用 mysql 二进制日志从删除数据库命令恢复?

    如何恢复使用 drop database 命令删除的 mysql 数据库 我可以访问二进制日志 这应该使这种类型的回滚成为可能 文档很糟糕 它暗示 DROP DATABASE 是可恢复的 但仅在我不熟悉的奇怪条件下http dev mysq
  • Flutter - 无线电动画未显示在 showDialog 上

    我正在尝试创建一个Radio in a showDialog 但是发生的动画Radio没有出现在showDialog 例如 当点击时foo2什么也没有发生 当你退出时showDialog然后回到它 foo2被选中 下面是代码和 gif 显示
  • C# 委托中的元帅 va_list

    我正在尝试用 c 来完成这项工作 C 标头 typedef void LogFunc const char format va list args bool Init uint32 version LogFunc log C 实现 stat
  • Java 同步和性能的一个方面

    我刚刚意识到我需要在某个方面同步大量数据收集代码 但性能是一个真正值得关注的问题 如果性能下降太多 我的工具就会被淘汰 我将分别写入 int 和 long 以及各种数组 ArrayList 和 Map 应用程序将有多个线程进行函数调用 这些
  • 如何使用 SASS 进行媒体查询?

    我已经通读了 SASS 文档 只能找到如何使用 scss 语法而不是 sass 语法进行媒体查询 sass 是具有严格的空白 没有大括号或分号的语法 如何使用 sass 语法进行媒体查询 media screen and min heigh
  • pcl::RANSAC 分割,获取云中的所有平面?

    我有一个点云库函数 可以检测点云中最大的平面 这很好用 现在 我想扩展此功能以分割云中的每个平面并将这些点复制到新的云中 例如 房间地板上有球体的场景将返回地板和墙壁 但不是球体 因为它不是平面的 如何扩展下面的代码以获得所有飞机 而不仅仅
  • 内部版本号中的分支名称

    我试图将分支名称放入内部版本号中 但找不到正确的参数 我正在使用内部版本号格式 teamcity build branch 0 它可以工作 但是当它尝试构建默认分支 dev 时 teamcity 将其命名为
  • 如何在 osgi 中从字节反序列化对象

    在我的 osgi 应用程序中 我有三个包 travel api table api and utils travel api依赖于取决于table api这取决于utils 注意travel api不直接依赖于utils 我使用 aQute
  • x86 上哪个写屏障更好:lock+addl 或 xchgl?

    Linux 内核使用lock addl 0 0 esp 作为写屏障 而 RE2 库使用xchgl 0 0作为写屏障 有什么区别 哪个更好 x86 也需要读屏障指令吗 RE2 将其读屏障函数定义为 x86 上的无操作 而 Linux 将其定义