斯科特对编程语言语用学的自旋锁存在一些困难。感谢您能否更清楚地解释它们。谢谢。如何理解螺旋锁的这些实现?
-
尽管所有这些算法是历史上重要的,一个实用 自旋锁需要在恒定时间和空间中运行,而这一个 需要的原子指令,做比加载或存储更多。 从20世纪60年代开始,硬件设计人员开始为他们的 处理器配备指令,读取,修改和写入位置为单个原子操作。最简单的这样的指令 被称为
test_and_set
。它将布尔变量设置为true,并且返回变量是否先前为假的指示。 鉴于test_and_set中,获得一个自旋锁几乎是微不足道的:while not test_and_set(L) –– nothing –– spin
什么的
L
的价值是什么意思?是否
test_and_set(L)
返回false当且仅当L
为真?它为什么作为自旋锁工作?
-
在实践中,在一个循环中嵌入test_and_set趋向于导致在多核或多处理器 机 不可接受量的通信,作为高速缓存一致性机制试图调和由多个内核试图获取写入 锁。这种硬件资源的过度需求被称为竞争,并且是大型机器上的良好性能的主要障碍。
为了降低争用,同步库的作者经常 采用测试和test_and_set锁,这与普通的自旋读 (SATIS音响由高速缓存编),直到它出现该锁是免费的(见 图13.8)。当一个线程释放一个锁时,当等待线程执行它们的test_and_sets时,总线或互连活动依然倾向于总线或互连活动,但至少这种活动只发生在临界区的 边界上。在大型机器上,通过实施退避策略可以进一步减少争用,其中尝试获取锁定的线程 在尝试再次尝试之前等待 一段时间,然后等待 。
type lock = Boolean := false; procedure acquire lock(ref L : lock) while not test and set(L) while L –– nothing –– spin procedure release lock(ref L : lock) L := false
图13.8简单的test-and-test_and_set锁。等待进程 以普通读取(加载)指令旋转,直到看起来锁定为 为空,然后使用test_and_set获取它。第一次访问是 test_and_set,用于在普通(无竞争)情况下的速度。
是否“通常的读出(负载)的说明”指的阅读
while L
L
指令 ?这种方式如何比第一个更好?