我想使用Interlocked.Add
方法,因为int
和long
的速度更快。我有其他类型的代码:
short x = Sum(source, range.Item1, range.Item2);
checked
{
lock (syncRoot)
result += x;
}
但是我发现Interlocked没有处理溢出。如何确定发生上溢或下溢? x
可以是正面的,也可以是负面的。
var x = Sum(source, range.Item1, range.Item2);
Interlocked.Add(ref result, x);
bool overflow = ...
if (overflow)
throw new OverflowException();
我在MSDN上找到了以下提示,但不知道如何实施此检查:
此方法通过包装来处理溢出条件:如果值为 location1是Int32.MaxValue,值是1,结果是 Int32.MinValue;如果value为2,则结果为(Int32.MinValue + 1);和 所以没有例外。
答案 0 :(得分:1)
Interlocked.Add
返回新值。如果新值小于旧值,则发生溢出。问题是你无法以这种方式获得旧值。
您可以使用CAS loop以原子方式读取旧值,检查溢出并以原子方式写入新值。
请注意,根本没有锁定互锁操作的比例。互锁操作仅仅是硬件锁。它们在绝对意义上更快,并且不会受到争用的影响。但是,以高频率执行此操作将无法从多个CPU中受益。