当前位置: 首页 > 知识库问答 >
问题:

为什么x86的INC指令不是原子指令?[副本]

赵光赫
2023-03-14

我读过,x86的INC指令不是原子指令。我的问题是为什么会这样?假设我们在x86-64上递增一个64位整数,我们可以用一条指令来递增,因为INC指令同时处理内存变量和寄存器。那么为什么它不是原子的呢?

共有3个答案

赵飞语
2023-03-14

从Agner Fog的软件优化资源:指令表中,除非您需要,否则您真的不想要有保证的原子操作。pdf(1996-2017):

带有锁前缀的指令具有很长的延迟,这取决于缓存组织和RAM速度。如果有多个处理器或内核或直接内存访问(DMA)设备,则所有锁定的指令将锁定缓存线以进行独占访问,这可能涉及RAM访问。即使在单处理器系统上,锁前缀通常也要花费100多个时钟周期。这也适用于带有内存操作数的XCHG指令。

汝跃
2023-03-14

现代x86处理器作为其执行管道的一部分,将x86指令“编译”成一组较低级别的操作;英特尔称这些为uOps,AMD rOps,但归结起来就是某些类型的单一x86指令由
这意味着,例如:

INC EAX

作为单个迷你操作执行,如uOp.inceax(让我这么称呼它——它们不公开)。
对于其他操作数,事情看起来会有所不同,比如:

INC DWORD PTR [ EAX ]

低级分解看起来更像:

uOp.load tmp_reg, [ EAX ]
uOp.inc tmp_reg
uOp.store [ EAX ], tmp_reg

因此,不会以原子方式执行。另一方面,如果您通过说LOCK INC[EAX]作为前缀,这将告诉管道的“编译”阶段以不同的方式进行分解,以确保满足原子性要求。

原因当然是其他人提到的——速度;如果不是总是需要,为什么要做原子的东西,而且一定要慢?

越胤
2023-03-14

为什么会这样?处理器内核仍然需要读取存储在内存位置的值,计算其增量,然后将其存储回内存。在读取和存储之间存在延迟,同时另一个操作可能会影响该内存位置。

即使在无序执行的情况下,处理器内核也足够“聪明”,不会被自己的指令绊倒,也不会负责在时间间隔内修改内存。然而,另一个核心可能发出了修改该位置的指令,DMA传输可能影响了该位置,或者其他硬件以某种方式触及了该内存位置。

 类似资料:
  • 我正在尝试创建一个愚蠢的自旋锁版本。浏览网页时,我在x86中遇到了一条名为“PAUSE”的汇编指令,该指令用于向处理器提示该CPU上当前正在运行自旋锁。英特尔手册和其他可用信息声明: 在大多数情况下,处理器使用此提示来避免内存顺序冲突,这大大提高了处理器性能。因此,建议在所有自旋等待循环中放置暂停指令。文档还提到“等待(一些延迟)”是指令的伪实现。 上段最后一行很直观,如果我抢锁不成功,我必须等一

  • 因此,我已经阅读了大约半年的关于x86处理器内部发生的事情。所以我决定尝试一下x86程序集的乐趣,只从80386指令开始,以保持它的简单性。(我主要是在学习,而不是优化) 几个月前我做了一个用C语言编写的游戏,所以我去那里用汇编代码从头重写了位图blitting函数。我不明白的是,循环的主要像素绘制主体使用C代码(18条指令)比我的汇编代码(只有7条指令,我几乎100%确定它不会跨越缓存行边界)更

  • 本文向大家介绍什么是JSP指令?,包括了什么是JSP指令?的使用技巧和注意事项,需要的朋友参考一下 JSP指令影响Servlet类的整体结构。它通常具有以下形式- 指令标记有三种类型- 序号 指令与说明 1 <%@ page ...%> 定义与页面相关的属性,例如脚本语言,错误页面和缓冲要求。 2 <%@ include ...%> 在翻译阶段包含文件。 3 <%@ taglib ...%> 声明

  • 问题内容: 我花了很多时间阅读AngularJS文档和一些教程,对于文档的难懂性,我感到很惊讶。 我有一个简单的,可以回答的问题,对于其他希望使用AngularJS的人也可能有用: 什么是AngularJS指令? 某个地方应该有一个简单,精确的指令定义,但是AngularJS网站提供了这些令人惊讶的无用定义: 在主页上: 指令是AngularJS中可用的独特而强大的功能。指令可让您发明特定于您的应

  • 所以我和一位面试官(你的标准人力资源经理)谈了他们在面试中真正想要的东西,他提到了一些关于测试JVM指令知识的东西(以及其他很多东西)。 我不知道那是什么,但我以为他说的是字节码指令。 我做了一些研究,似乎在“JVM指令”上找不到任何东西,我只找到了字节码指令的引用,我已经知道了字节码指令。 例如:http://docs.oracle.com/javase/specs/jvms/se7/html/

  • RDTSC 指令的英特尔手册警告说,当 RDTSC 实际执行时,无序执行可能会更改,因此他们建议在其前面插入 CPUID 指令,因为 CPUID 将序列化指令流(CPUID 永远不会无序执行)。我的问题很简单:如果他们有能力进行指令序列化,为什么他们不进行RDTSC序列化?它的全部意义似乎是获得周期准确的时间。是否存在您不希望在它之前使用序列化指令的情况? 较新的英特尔CPU有一个单独的RDTSC