Tim*_*imo 8 c# multithreading interlocked compare-and-swap spinwait
以下是基于的互锁方法的实现Interlocked.CompareExchange
。
这段代码SpinWait
在重复之前是否宜使用自旋?
public static bool AddIfLessThan(ref int location, int value, int comparison)
{
int currentValue;
do
{
currentValue = location; // Read the current value
if (currentValue >= comparison) return false; // If "less than comparison" is NOT satisfied, return false
}
// Set to currentValue+value, iff still on currentValue; reiterate if not assigned
while (Interlocked.CompareExchange(ref location, currentValue + value, currentValue) != currentValue);
return true; // Assigned, so return true
}
Run Code Online (Sandbox Code Playgroud)
我已经看到SpinWait
在这种情况下使用过,但是我的理论是它应该是不必要的。毕竟,循环仅包含少量指令,并且总是有一个线程在进行中。
假设有两个线程竞相执行此方法,并且第一个线程立即成功执行,而第二个线程最初不做任何更改,必须重申。没有其他竞争者,第二个线程是否有可能在第二次尝试时失败?
如果该示例的第二个线程在第二次尝试上不能失败,那么使用?可以得到什么SpinWait
?如果不太可能发生一百个线程争分夺秒地执行该方法的情况,可以省去几个周期?
我的非专家意见是,在这种特殊情况下,两个线程偶尔调用AddIfLessThan
, aSpinWait
是不需要的。如果两个线程都在调用,这可能会很有用AddIfLessThan
在紧密循环中调用,则这可能是有益的,这样每个线程都可以在某些 \xce\xbcsec 内不间断地取得进展。
AddIfLessThan
实际上,我做了一个实验,测量了在紧密循环中调用一个线程与两个线程的性能。两个线程需要几乎四倍的时间才能进行相同数量的循环(累计)。添加SpinWait
到混合中使得两个线程仅比单线程慢一点。