pax*_*blo 6 x86 linux-kernel spinlock
阅读Understanding the Linux kernel (Bovet & Cesati),内核同步章节后,我们知道自旋锁获取代码归结为:
1: lock:
btsl $0, slp
jnc 3
2: testb $1, slp
jne 2
jmp 1
3:
Run Code Online (Sandbox Code Playgroud)
现在我原本以为嵌套循环似乎很浪费你可以实现类似的东西:
1: lock:
btsl $0, slp
jc 1
Run Code Online (Sandbox Code Playgroud)
这会简单得多.但是,我知道为什么他们这样做,因为lock影响其他CPU和时间btsl比大的简单testb.
我无法理解的一件事是旋转锁的后续释放.该书指出它产生以下结果:
lock:
btrl $0, slp
Run Code Online (Sandbox Code Playgroud)
我的问题基本上是为什么?在我看来,lock/mov-immediate组合更快.
您不需要将旧状态转换为进位标志,因为遵循内核无错误的规则(假设在所述内核中的许多其他位置),旧状态将为1(您不会试图释放它,如果你还没有获得它).
a mov比a快得多btrl,至少在386上.
那我错过了什么?
在后来的芯片上更改了那些指令的时间吗?
自书籍印刷以来内核是否已更新?
这本书是完全错误的(或显示简化说明)?
我是否错过了快速指令不满足的CPU之间同步化的其他方面?
Mic*_*kis 10
好吧,Understanding the Linux Kernel老了.自编写以来,Linux内核已更新为使用所谓的票证自旋锁.锁定基本上是一个16位数量,分为两个字节:让我们调用一个Next(如分配器中的下一张票)和另一个Owner(如计数器上的'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");
}
Run Code Online (Sandbox Code Playgroud)
因为inc快了大约8或9倍btr.
希望这可以帮助; 如果没有,我会很乐意深入挖掘.
| 归档时间: |
|
| 查看次数: |
1310 次 |
| 最近记录: |