【问题标题】:mov vs xchg in spin lock implementatoin [duplicate]自旋锁实现中的 mov vs xchg [重复]
【发布时间】:2021-01-22 19:07:43
【问题描述】:

我正在阅读这个online book on x86,我很好奇他们用于实现自旋锁的示例代码中的实现细节。在示例中,他们使用 xchg 将内存位置设置为 0 而不是 mov,我试图理解为什么会做出这样的选择。

在自旋锁示例中,有一个函数spinUnlock0 放入内存位置[sLock][sLock] 被设置为 0 如果锁是空闲的,1 被获取时。 spinUnlock 函数将 [sLock] 设置为 0 以释放锁。代码如下:

spinUnlock:
    push    ebp
    mov ebp, esp
    mov eax, 0
    xchg    eax, [sLock]
    pop ebp
    ret

为什么使用mov eax, 0; xchg eax, [sLock][sLock] 设置为0 而不是mov [sLock], 0?在调用spinUnlock 之后,eax 寄存器不用于任何操作。我知道xchg 会锁定内存位置,但如果mov 已经是原子的,则不需要锁定。

【问题讨论】:

  • mov 是原子的,但不会强加内存排序。 xchg 是后者。

标签: assembly x86 spinlock


【解决方案1】:

只有作者才能说出做出选择的原因。

单个mov dword [sLock],0 可以正常工作;而xchg eax, [sLock](隐含lock)可能更昂贵(对于性能和代码大小而言)。

示例的所有代码都很糟糕(例如,spinLock 例程中没有pause,尽管在根本不应该使用pause 的地方应该使用它);他们选择的例子也不好。

注意:在用户空间使用自旋锁“几乎永远不会”正常,因为操作系统可能会在您获得锁之后但在您释放它之前执行任务切换,从而导致所有其他任务浪费大量 CPU时间在旋转,没有希望获得锁定。

【讨论】:

  • 使用 xchg 是因为它意味着内存屏障。如果您想要一个具有内存屏障语义的存储,这实际上是推荐的。
  • @fuz:当然;但是对于示例代码,您不希望这样(由于lock 在将来的任何重新获取尝试中使用,因此存储转发不会成为问题,因此“相对强排序”足以避免障碍)。
  • “所有示例的代码都很糟糕”:很高兴知道这一点。我最好找一个不同的来源,而不是继续看这本书。
猜你喜欢
  • 2016-08-12
  • 2021-12-27
  • 1970-01-01
  • 2020-03-27
  • 2021-10-17
  • 2014-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多