2

斯科特对编程语言语用学的自旋锁存在一些困难。感谢您能否更清楚地解释它们。谢谢。如何理解螺旋锁的这些实现?

  1. 尽管所有这些算法是历史上重要的,一个实用 自旋锁需要在恒定时间和空间中运行,而这一个 需要的原子指令,做比加载或存储更多。 从20世纪60年代开始,硬件设计人员开始为他们的 处理器配备指令,读取,修改和写入位置为单个原子操作。最简单的这样的指令 被称为test_and_set。它将布尔变量设置为true,并且返回变量是否先前为假的指示。 鉴于test_and_set中,获得一个自旋锁几乎是微不足道的:

    while not test_and_set(L) 
        –– nothing –– spin 
    

    什么的L的价值是什么意思?

    是否test_and_set(L)返回false当且仅当L为真?

    它为什么作为自旋锁工作?

  2. 在实践中,在一个循环中嵌入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 LL指令 ?

    这种方式如何比第一个更好?

回答

3

L的意思是什么?

L在锁定空闲时设置为0,锁定被某人锁定时设置为1。

当且仅当L为真时,test_and_set(L)是否返回false?

是的,它在您引用的引用中有明确的描述:“返回变量之前是否为false”的指示。

它为什么作为自旋锁?

它满足上述变量L的不变量。

“普通读取(加载)指令”是指L读取L的指令吗?

是的。

这种方式如何比第一个更好?

检查L是0通过“通常的读”指令涉及小于通过使用test_and_set指令“量的多核或多处理器机器上的通信”。所以,当一个内核在锁上旋转时,其他内核受影响较小。