加入收藏 | 设为首页 | 会员中心 | 我要投稿 财气旺网 - 财气网 (https://www.caiqiwang.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

x86 – Linux / SMP自旋锁不必要地慢吗?

发布时间:2020-12-26 22:30:32 所属栏目:Linux 来源:网络整理
导读:在阅读了解 Linux内核(Bovet Cesati)之后,关于内核同步的章节指出自旋锁获取代码归结为: 1: lock: btsl $0,slp jnc 32: testb $1,slp jne 2 jmp 13: 现在我原本以为嵌套循环似乎很浪费你可以实现类似的东西: 1: lock: btsl $0,slp jc 1 这会简单得多.但是,

在阅读了解 Linux内核(Bovet& Cesati)之后,关于内核同步的章节指出自旋锁获取代码归结为:

1: lock:
   btsl    $0,slp
   jnc     3
2: testb   $1,slp
   jne     2
   jmp     1
3:

现在我原本以为嵌套循环似乎很浪费你可以实现类似的东西:

1: lock:
   btsl    $0,slp
   jc      1

这会简单得多.但是,我知道为什么他们这样做,因为锁影响其他CPU并且btsl的时间比一个简单的testb的时间更大.

我无法理解的一件事是旋转锁的后续释放.该书指出它产生以下结果:

lock:
   btrl    $0,slp

我的问题基本上是为什么?在我看来,lock / mov-immediate组合更快.

您不需要将旧状态转换为进位标志,因为遵循内核无错误的规则(假设在所述内核中的许多其他位置),旧状态将为1(您不会试图释放它,如果你还没有获得它).

并且mov比btrl快得多,至少在386上.

那我错过了什么?

在后来的芯片上更改了那些指令的时间吗?

自书籍印刷以来内核是否已更新?

这本书是完全错误的(或显示简化说明)?

我是否错过了快速指令不满足的CPU之间同步化的其他方面?

解决方法

好吧,了解Linux内核已经过时了.自编写以来,Linux内核已更新为使用所谓的票证自旋锁.锁定基本上是一个16位数量,分为两个字节:让我们调用一个Next(就像分配器中的下一个票证)和另一个所有者(比如计数器上的’Now Serving’号码).初始化自旋锁,两个部分都设置为零.锁定注意到自旋锁的值并递增下一步,原子地.如果递增前的Next值等于Owner,则已获得锁定.否则,它会旋转,直到所有者增加到正确的值,依此类推.

相关代码在asm/spinlock.h(对于x86).解锁操作确实比书中说的更快更简单:

static __always_inline void __ticket_spin_unlock(arch_spinlock_t *lock)
{
    asm volatile(UNLOCK_LOCK_PREFIX "incb %0"
         : "+m" (lock->slock)
         :
         : "memory","cc");
}

因为inc比btr快约8或9倍.

希望这可以帮助;如果没有,我会很乐意深入挖掘.

(编辑:财气旺网 - 财气网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!