Volatile.Read
的实现只是在读取之后插入一个内存屏障:
public static int Read(ref int location)
{
var value = location;
Thread.MemoryBarrier();
return value;
}
因此,使用这样的方法......
return Volatile.Read(ref _a) + Volatile.Read(ref _b);
......相当于:
var a = _a;
Thread.MemoryBarrier();
var b = _b;
Thread.MemoryBarrier();
return a + b;
鉴于上述情况,如果参数不是ref
,结果行为是否相同?
public static int Read(int value)
{
Thread.MemoryBarrier();
return value;
}
我想ref
参数仅用于防止程序员传递除变量之外的其他内容,例如Volatile.Read(2 + 3)
。传入变量时,任何人都可以看到ref
的任何其他原因吗?
答案 0 :(得分:9)
这不是真实的代码在完成抖动之后的样子。 Volatile.Read()是内在。一个昂贵的词,意味着抖动根本不会编译方法,而是用机器代码的特定于处理器的版本替换它。您找到的代码只是一个占位符,可以作为没有良好抖动的机器上的后备。理论上
您可以使用Debug>查看计算机上的内容。 Windows>拆卸。您必须切换到发布版本并使用工具>选项>调试>一般>解开“抑制JIT优化”。大多数程序员会对他们看到的内容感到满意:
04CF0450 mov ecx,dword ptr ds:[7C43ACh]
或换句话说:没有。只是简单的记忆阅读没有障碍。 Intel / AMD内核具有强大的内存模型,不需要屏障。但是,比方说,ARM核心确实需要变量的地址。 Itanium也很弱,但它的抖动已经停止。
请注意,虽然你可能会感到高兴,但这也是一个相当糟糕的消息。你基本上不能依赖你的开发机器上的程序测试,并得出结论它是足够好的。或者换句话说,没有办法告诉你应该使用Volatile但是你忘记了。只有在设备上运行你的程序才会给你一个提示你弄错了。跳过lock
:)确实需要很大的勇气。
比较那样的几个内在函数,例如Math.Sqrt()。大多数处理器都将它作为内置的机器代码指令。
答案 1 :(得分:0)
因为在.NET中,默认情况下参数是按值传递的。