这个问题已经在这里有一个答案:
- 可以NUM ++是原子的“廉政NUM”? 13个回答
我读过的x86 INC指令不是原子。 我的问题是怎么来的? 假设我们正在增加对X86-64 64位整数,我们可以用一条指令去做,因为INC指令与两个内存变量和注册工作。 那么怎么来它不是原子?
这个问题已经在这里有一个答案:
我读过的x86 INC指令不是原子。 我的问题是怎么来的? 假设我们正在增加对X86-64 64位整数,我们可以用一条指令去做,因为INC指令与两个内存变量和注册工作。 那么怎么来它不是原子?
为什么它会是什么? 处理器核心仍然需要读取存储在该存储器位置中的值,计算出它的增量,然后将其存储回。 有读取和存储之间的等待时间,并在平均时间的另一个操作可能会影响该内存位置。
即使在乱序执行,处理器内核是“智能”足以不超过自己的指令跳闸,将不负责在时间上的差距修改此内存。 然而,另一个核心可以已经发布的修改时位置的指令,DMA传输可能会影响该位置,或其他硬件莫名其妙地感动,内存位置。
现代x86处理器作为其执行流水线的一部分“编译” x86指令到较低级别的操作集合; 英特尔称这些微指令,AMD ROPS,但它归结为是,某些类型的单x86指令得到由CPU 几个步骤,在实际的功能单元执行。
这意味着,例如,认为:
INC EAX
被作为一个“小型运”等执行uOp.inc eax
(让我称呼它-他们不暴露)。
对于其他操作数的东西会看起来有所不同,如:
INC DWORD PTR [ EAX ]
低层次的分解,尽管看起来更像是:
uOp.load tmp_reg, [ EAX ]
uOp.inc tmp_reg
uOp.store [ EAX ], tmp_reg
因此不自动执行。 如果你说前缀另一方面LOCK INC [ EAX ]
即会告诉管道的“编译”的阶段以不同的方式分解,以确保原子性要求得到满足。
这样做的原因当然是因为其他人所说 - 速度; 为什么使一些原子和一定要慢,如果不是总是要求?
你真的不想要保证原子操作,除非你需要它,从昂纳雾的软件优化资源 : instruction_tables.pdf (1996年至2017年):
配合LOCK前缀指令有很长的潜伏期依赖于缓存组织和可能RAM速度。 如果有多个处理器核心或直接或存储器存取(DMA)设备,那么所有锁定指令将锁定独占访问的缓存行,这可能涉及RAM访问。 LOCK前缀通常费用超过一百个时钟周期,即使是在单处理器系统。 这也适用于与存储操作数指令XCHG。