我正在开发一个需要long
具有可变语义的类型的组件。
由于volatile long
.NET 中没有,我创建了一个简单的包装器类型,它使用类处理读/写访问Volatile
。
我不确定我应该使用类还是结构,所以我决定对它们都进行测试,但我遇到了一个非常奇怪的行为。
这是测试代码:
internal class Program
{
private class VolatileLongClass
{
private long value;
public long Value
{
get { return Volatile.Read(ref value); }
set { Volatile.Write(ref this.value, value); }
}
}
private struct VolatileLongStruct
{
private long value;
public long Value
{
get { return Volatile.Read(ref value); }
set { Volatile.Write(ref this.value, value); }
}
}
private static void Main()
{
const int iterations = 10;
var totalTime = 0L;
for (var i = 0; i < iterations; i++)
{
var watch = Stopwatch.StartNew();
var volatileLong = new VolatileLongClass(); //<-- change to VolatileLongStruct
for (var j = 0L; j < 10 * 1000 * 1000; j++)
volatileLong.Value = j;
var msElapsed = watch.ElapsedMilliseconds;
Console.Out.WriteLine("Ms Elapsed = {0}", msElapsed);
totalTime += msElapsed;
}
Console.Out.WriteLine("Avg = {0:N2}", (double) totalTime / iterations);
}
}
我为 VolatileLongStruct 得到的输出:
Ms Elapsed = 109
Ms Elapsed = 109
Ms Elapsed = 109
Ms Elapsed = 109
Ms Elapsed = 109
Ms Elapsed = 109
Ms Elapsed = 109
Ms Elapsed = 109
Ms Elapsed = 109
Ms Elapsed = 109
Avg = 109.00
struct 的上述输出是一致的。但是,VolatileLongClass 的输出是:
Ms Elapsed = 17558 <-- ***
Ms Elapsed = 105
Ms Elapsed = 105
Ms Elapsed = 105
Ms Elapsed = 105
Ms Elapsed = 105
Ms Elapsed = 17541 <-- ***
Ms Elapsed = 105
Ms Elapsed = 105
Ms Elapsed = 105
Avg = 3,593.90
如您所见,某些迭代存在很大的时间差异。花费异常时间的确切迭代略有不同,但至少有一个迭代存在一致的问题。
有人可以解释一下为什么类成员上的易失性写入(有时)比结构成员上花费的时间更长吗?
顺便说一句,上述结果是使用 .Net 4.5 和 Release 构建产生的