我正在用c++编写多线程应用程序,其中性能至关重要。在线程之间复制小结构时,我需要使用很多锁定,为此,我选择使用自旋锁。
我对此进行了一些研究和速度测试,发现大多数实现速度大致相同:
__asm {}
一起使用内联汇编,它的得分约为70个时间单位,即,但我不确定是否已创建适当的内存屏障。 编辑:这里给出的时间是2个线程锁定和解锁自旋锁所需的时间1,000,000次。
我知道这没有太大的区别,但是由于自旋锁是一个使用率很高的对象,因此人们会认为程序员会同意以最快的方式制造自旋锁。谷歌搜索导致许多不同的方法。我认为如果使用内联汇编和使用
CMPXCHG8B
指令而不是比较32位寄存器来实现,this aforementioned method最快。 此外,还必须考虑内存障碍,这可以通过LOCK CMPXHG8B(我认为?)来完成,它可以保证对内核之间共享内存的“专有权利”。最后(有人建议),对于,繁忙的等待应伴随NOP:REP 进行,这将使超线程处理器能够切换到另一个线程,但是我不确定这是否成立?从我对不同自旋锁的性能测试中可以看出,它们之间并没有太大区别,但是出于纯粹的学术目的,我想知道哪一个最快。但是,由于我在汇编语言和内存屏障方面的经验极为有限,如果有人可以为我在以下模板中提供的LOCK CMPXCHG8B和适当内存屏障所提供的最后一个示例编写汇编代码,我将很高兴:
__asm
{
spin_lock:
;locking code.
spin_unlock:
;unlocking code.
}
最佳答案
看看这里:
x86 spinlock using cmpxchg
多亏了Cory Nelson
__asm{
spin_lock:
xorl %ecx, %ecx
incl %ecx
spin_lock_retry:
xorl %eax, %eax
lock; cmpxchgl %ecx, (lock_addr)
jnz spin_lock_retry
ret
spin_unlock:
movl $0 (lock_addr)
ret
}
另一个消息说:
http://www.geoffchappell.com/studies/windows/km/cpu/cx8.htm
lock cmpxchg8b qword ptr [esi]
is replaceable with the following sequence
try:
lock bts dword ptr [edi],0
jnb acquired
wait:
test dword ptr [edi],1
je try
pause ; if available
jmp wait
acquired:
cmp eax,[esi]
jne fail
cmp edx,[esi+4]
je exchange
fail:
mov eax,[esi]
mov edx,[esi+4]
jmp done
exchange:
mov [esi],ebx
mov [esi+4],ecx
done:
mov byte ptr [edi],0
这是关于无锁与锁实现的讨论:
http://newsgroups.derkeiler.com/Archive/Comp/comp.programming.threads/2011-10/msg00009.html
关于c++ - 最快的内联组装自旋锁,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11959374/