在.Net中是否有相当于XADD的命令?毕竟,这是锁定/检查关键部分锁定或确保多线程环境中准确增量的最有效方法.
我查看了IL操作码,但找不到相应的操作码.
获取锁定比使用简单的CPU指令要多得多.试图获得它而不是获得它的成本非常高.记录在2000到10,000台机器指令之间.线程上下文切换到另一个进程中的线程的数字越大,这需要重新加载虚拟内存页面转换表.
在多核CPU上有意义的一种非常常见的策略是自旋等待.代码进入紧密循环,大量燃烧CPU周期,试图获取锁定.它在这个循环中花费的确切时间在技术上是一个可调项,但在实践中并没有太大的区别.
Anyhoo,它是CLR的工作,编译器是隐藏实现细节.执行此操作的一个核心类是Monitor类.它在C#中使用lock语句时使用,例如,编译器自动将其转换为Monitor.Enter调用,自动生成try和finally块,finally块执行Leave()方法.
这些方法的实现在CLR中.那里有相当多的代码,另一件事就是处理"公平".这可以确保线程不会饿死,试图获得锁定.该代码是用C++编写的,与原始CPU指令相差甚远.它最终归结为实现实际锁定的实际代码.是的,这是用汇编编写的,至少在CLR的共享源版本中.该代码存在于PAL(平台适配器层)中,其x86版本如下所示:
FASTCALL_FUNC CompareExchangeMP,12 _ASSERT_ALIGNED_4_X86 ecx mov eax, [esp+4] ; Comparand lock cmpxchg [ecx], edx retn 4 ; result in EAX FASTCALL_ENDFUNC CompareExchangeMP
带锁定前缀的cmpxchng CPU指令是实现锁定的典型指令.您的xadd也被覆盖,用于Interlocked.Add:
FASTCALL_FUNC ExchangeAddUP,8 _ASSERT_ALIGNED_4_X86 ecx xadd [ecx], edx ; Add Value to Target mov eax, edx retn FASTCALL_ENDFUNC ExchangeAddUP
但这通常不用于锁.如果您想亲眼看到这个,请下载SSCLI20源代码并查看clr\src\wm\i386\asmhelpers.asm.是否实际在CLR的当前发布版本中使用是一个悬而未决的问题.这是非常核心的,有点可能.Monitor方法实现在clr\vm\syncblk.cpp,AwareLock类中.我很确定它的SSCLI20版本不是你机器上运行的版本,他们一直在修改"公平"算法.