cmpxchg 和 btr bts 之间的区别

gyb*_*ddp 3 x86 locking

btr,bts指令简单,可以锁定共享资源。

为什么该指令cmpxchg存在?这两个指令有什么不同?

gee*_*aur 5

IIRC(已经有一段时间了)lock btr比 更昂贵cmpxchg,后者旨在自动锁定总线以实现原子性并尽快执行此操作。(具体来说,lock INSTR在整个指令周期内保持总线锁定,并进行完全无效,但cmpxchg锁定和无效的微代码仅在绝对需要时才进行,以便成为最快的同步原语。)

(编辑:根据此消息,它还支持更高级的(用户)无锁策略。

CMPXCHG [memaddr], reg将内存位置与EAX(或AX, 或 AL) 进行比较;如果它们相同,则将源操作数写入内存位置。显然,这可以以与 相同的方式使用XCHG,但它也可以以另一种非常有趣的方式使用,即无锁同步。

假设您有一个更新共享数据结构的进程。为了确保原子性,它生成数据结构的私有更新副本;当它完成时,它会自动更新曾经指向旧数据结构的单个指针,以便它现在指向新数据结构。

如果进程有可能失败,那么直接的方法将很有用,并且它为您提供了原子性。但我们可以稍微修改这个过程,以允许多个同时更新,同时确保正确性。

该进程只是自动地将指针与开始工作时的值进行比较,如果是,则使指针指向新的数据结构。如果其他进程同时更新了数据结构,则比较将失败并且交换不会发生。在这种情况下,该过程必须从新更新的数据结构重新开始。

(这本质上是软件事务内存的原始形式。)

  • 因为这在多核/多处理器系统中还不够好。没有什么可以阻止另一个 CPU 窃取互斥锁并翻转相同的位,甚至更改您下面的整个值。正如目前所实现的那样,内存芯片无法在位级别“物理”寻址。您设置并锁存一个地址,然后读取或发送整个字节宽度的值。这和“锁存器”部分(基本上是“这是我的最终值”硬件互斥锁,因为同一总线上的许多设备在更改它时可能会导致瞬态)是您需要担心锁定总线的原因。 (2认同)
  • `cmpxchg` 不是原子的。您需要“lock cmpxchg”以使操作原子化。与“btr”/“bts”/“btc”一样,不带“lock”的“cmpxchg”只有在与同一线程中的另一个操作(例如来自信号处理程序)同步时才有用。您可能会想到“xchg”,它总是表现得好像有一个“lock”前缀。 (2认同)