Kag*_*nar 18
为什么会这样?处理器内核仍然需要读取存储在存储器位置的值,计算它的增量,然后将其存储回来.读取和存储之间存在延迟,同时另一个操作可能会影响该存储器位置.
即使执行无序,处理器内核也"足够智能",不会跳过自己的指令,也不负责在时间间隔内修改此内存.但是,另一个核心可能已发出修改该位置的指令,DMA传输可能会影响该位置,或者其他硬件以某种方式触及该存储器位置.
Fra*_*kH. 18
现代x86处理器作为其执行流程的一部分,将x86指令"编译"为较低级别的操作集; 英特尔称之为uOps,AMD rOps,但它归结为某些类型的单个x86指令由CPU中的实际功能单元执行为几个步骤.
这意味着,例如,:
INC EAX
Run Code Online (Sandbox Code Playgroud)
被作为单个"迷你操作"执行uOp.inc eax
(让我称之为 - 他们没有暴露).
对于其他操作数,事物看起来会有所不同,例如:
INC DWORD PTR [ EAX ]
Run Code Online (Sandbox Code Playgroud)
低级分解虽然看起来更像:
uOp.load tmp_reg, [ EAX ]
uOp.inc tmp_reg
uOp.store [ EAX ], tmp_reg
Run Code Online (Sandbox Code Playgroud)
因此不是原子地执行的.另一方面,如果你在前缀中说LOCK INC [ EAX ]
,那将告诉管道的"编译"阶段以不同的方式分解,以确保满足原子性要求.
其原因当然是其他人提到的 - 速度; 为什么要做一些原子的东西,如果不总是需要的话必然要慢