assembly 锁能避免lr/sc的“虚假失败”吗

cidc1ykv  于 2023-06-06  发布在  其他
关注(0)|答案(1)|浏览(297)

我学习了大卫A. Patterson,并在第254页的Elaboration中有以下代码
以下是书籍内容和相关代码:
虽然上面的代码实现了原子交换,但下面的代码将更有效地在寄存器x20中的位置获取锁,其中0的值表示锁空闲,1表示获取锁:

addi x12, x0, 1
 // copy locked value
again: lr.d x10, (x20)
 // load-reserved to read lock
bne x10, x0, again
 // check if it is 0 yet
sc.d x11, x12, (x20)
 // attempt to store new value
bne x11, x0, again
 // branch if store fails

加锁后由**(基于)原始更改
由于load-reserved返回初始值,而store-conditional只有在成功时才返回0,因此以下序列在x20的内容指定的内存位置
上实现**原子交换:

again:lr.d x10, (x20)
 // load-reserved
sc.d x11, x23, (x20)
 // store-conditional
bne x11, x0, again
 // branch if store fails
addi x23, x10, 0
 // put loaded value in x23

1-书上说通过addi x12, x0, 1 // copy locked value将锁添加到代码中“更有效”,我不知道它在哪里
2-我认为这种锁无法避免基于“缓存线”硬件设计的“虚假故障”,对吗?

rnmwe5a2

rnmwe5a21#

我认为作者的意思是比do{}while(x20->exchange(1) == 0)更少的指令,这是使用他们的交换函数来获取自旋锁的明显方式。(这是他们的循环所做的。在C++术语中,它有点像do{}while(! lock.cas_weak(0, 1));,但他们关于asm效率的观点是特定于LL/SC的)
当负载看到非零值时,根本不存储也可能是有益的。(所以这个核心在另一个核心向它存储了0之后才能对缓存行做任何有用的事情时,它不会独占缓存行的所有权。)但是我不确定lr.d是否会在预期SC时尝试获得独占所有权(发送RFO =读取所有权)。如果比较失败,它至少不会弄脏该高速缓存行,因此不必写回它。
这也可以减少多个线程等待锁的活锁问题,所有线程都运行这个循环。
有关具有多个旋转、只读与原子RMW访问参见通过内联汇编的内存操作周围的锁(x86,只有单指令CAS_strong,而不是LL/SC)。
1.正确,您无法避免LL/SC指令的伪故障。

相关问题