很抱歉提出了一个很长的问题,但是有一个Jon引用,所以这对一些人来说可能是值得的。
简而言之::
在Mono框架中运行Interlocked.Read / Interlocked.Exchange似乎要比在.NET框架中运行时慢得多。我很想知道为什么。
In long:
我想要一个32位平台的线程安全的双面,所以我做了这个结构:
public interface IThreadSafeDouble
{
double Value { get; set; }
}
public struct LockedThreadSafeDouble : IThreadSafeDouble
{
private readonly object Locker;
private double _Value;
public double Value
{
get { lock (Locker) return _Value; }
set { lock (Locker) _Value = value; }
}
public LockedThreadSafeDouble(object init)
: this()
{
Locker = new object();
}
}然后我读了Jon对this question的回答,所以我创建了这个结构:
public struct InterlockedThreadSafeDouble : IThreadSafeDouble
{
private long _Value;
public double Value
{
get { return BitConverter.Int64BitsToDouble(Interlocked.Read(ref _Value)); }
set { Interlocked.Exchange(ref _Value, BitConverter.DoubleToInt64Bits(value)); }
}
}然后我写了这个测试:
private static TimeSpan ThreadSafeDoubleTest2(IThreadSafeDouble dbl)
{
var incrementTarg = 10000000;
var sw = new Stopwatch();
sw.Start();
for (var i = 0; i < incrementTarg; i++, dbl.Value++);
sw.Stop();
return sw.Elapsed;
}
private static void ThreadSafeTest()
{
var interlockedDbl = new InterlockedThreadSafeDouble();
var interlockedTim = ThreadSafeDoubleTest2(interlockedDbl);
var lockedDbl = new LockedThreadSafeDouble(true);
var lockedTim = ThreadSafeDoubleTest2(lockedDbl);
System.Console.WriteLine("Interlocked Time: " + interlockedTim);
System.Console.WriteLine("Locked Time: " + lockedTim);
}
public static void Main(string[] args)
{
for (var i = 0; i < 5; i++)
{
System.Console.WriteLine("Test #" + (i + 1));
ThreadSafeTest();
}
System.Console.WriteLine("Done testing.");
System.Console.ReadLine();
}我使用.NET框架获得了这个结果:

这个结果使用Mono框架:

我在同一台机器(Windows )上运行了两次测试,测试结果是一致的。我很想知道为什么Interlocked.Read/Interlocked.Exchange在Mono框架上的执行速度似乎要慢得多。
更新:
我编写了以下简单的测试:
long val = 1;
var sw = new Stopwatch();
sw.Start();
for (var i = 0; i < 100000000; i++) {
Interlocked.Exchange(ref val, 2);
// Interlocked.Read(ref val);
}
sw.Stop();
System.Console.WriteLine("Time: " + sw.Elapsed);.NET框架始终使用Exchange和Read返回~2.5秒。Mono框架返回~5.1秒。
发布于 2012-02-08 21:50:08
得出性能结论并不容易。在第一个例子中,long<->双转换可能是重要的因素。通过将所有双倍更改为longs (并删除转换),这是我在Windows中使用32位Mono的时候:
Test #1
Interlocked Time: 00:00:01.2548628
Locked Time: 00:00:01.7281594
Test #2
Interlocked Time: 00:00:01.2466018
Locked Time: 00:00:01.7219013
Test #3
Interlocked Time: 00:00:01.2590181
Locked Time: 00:00:01.7443508
Test #4
Interlocked Time: 00:00:01.2575325
Locked Time: 00:00:01.7309012
Test #5
Interlocked Time: 00:00:01.2593490
Locked Time: 00:00:01.7528010
Done testing.因此,互锁的实现并不是这里最大的因素。
但是接下来是第二个没有转换的例子。为什么会这样?我认为答案是循环展开,在.NET JIT编译器中做得更好。但这只是猜测。如果要比较现实场景中的互锁性能,可以(至少)有两个选项:
在实际的scenario.
的确切实现。
还请注意,上述实现提供的唯一保证是您不会观察到撕裂。例如,它没有给您(通常需要的)保证,如果两个线程正在递增值,之和将是正确的(也就是说,它将考虑所有的增量)。
https://stackoverflow.com/questions/9179461
复制相似问题