.NET 内存模型、 volatile 变量和测试设置 : what is guaranteed?

标签 .net synchronization volatile memory-fences test-and-set

我知道 .NET 内存模型(在 .NET Framework 上;不紧凑/微型/silverlight/mono/xna/what-have-you)保证对于某些类型(最显着的原始整数和引用)操作保证是原子。

此外,我相信 x86/x64 测试和设置指令(和 Interlocked.CompareExchange)实际上引用了全局内存位置,所以如果它成功了另一个 Interlocked.CompareExchange会看到新的值(value)。

最后,相信volatile关键字是编译器的指令,以尽快传播读写操作,并且不重新排序有关此变量的操作(对吗?)。

这导致了几个问题:

  • 我上面的信念正确吗?
  • Interlocked.Read没有 int 的重载,仅用于 long(这是 2 个 WORD,因此通常不会以原子方式读取)。我一直假设 .NET 内存模型保证在读取整数/引用时会看到最新的值,但是对于处理器缓存、寄存器等。我开始看到这可能是不可能的。那么有没有办法强制重新获取变量?
  • volatile 是否足以解决整数和引用的上述问题?
  • 在 x86/x64 上,我可以假设...

  • 如果有两个全局整数变量 x 和 y,都初始化为 0,如果我写:
    x = 1;
    y = 2;
    

    该 NO 线程将看到 x = 0 和 y = 2(即写入将按顺序发生)。如果它们是不稳定的,这会改变吗?

    最佳答案

  • 只有对最多 32 位宽(在 x64 系统上为 64 位宽)的变量的读取和写入是原子的。所有这一切都意味着您不会阅读 国际并获得半写值。这并不意味着算术是原子的。
  • 互锁操作也充当内存屏障,所以是的,Interlocked.CompareExchange将看到更新的值。
  • this page .易变并不意味着有序。一些编译器可能会选择不对 volatile 变量的操作重新排序,但 CPU 可以自由地重新排序。如果您想阻止 CPU 重新排序指令,请使用(完整)内存屏障。
  • 内存模型确保读取和写入是原子的,使用 volatile 关键字确保读取总是来自内存,而不是来自寄存器。所以你会看到最新的值。这是因为 x86 CPU 会在适当的时候使缓存失效——见 thisthis .另见 InterlockedCompareExchange64了解如何以原子方式读取 64 位值。
  • 最后,最后一个问题。答案是一个线程实际上可以看到x = 0y = 2 ,并且使用 volatile 关键字不会改变这一点,因为 CPU 可以自由地重新排序指令。你需要一个内存屏障。

  • 概括:
  • 编译器可以自由地重新排序指令。
  • CPU 可以自由地重新排序指令。
  • 字大小的读取和写入是原子的。算术和其他操作不是原子操作,因为它们涉及读取、计算和写入。
  • 从内存中读取字大小将始终检索最新值。但大多数时候你不知道你是否真的在从内存中阅读。
  • 完整的内存屏障停止 (1) 和 (2)。大多数编译器允许您自行停止 (1)。
  • volatile 关键字确保您从内存中读取 - (4)。
  • 互锁操作(锁前缀)允许多个操作是原子的。例如,读+写(InterlockedExchange)。或者读+比较+写(InterlockedCompareExchange)。它们还充当内存屏障,因此 (1) 和 (2) 停止。他们总是写入内存(显然),所以(4)是确保的。
  • 关于.NET 内存模型、 volatile 变量和测试设置 : what is guaranteed?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2099711/

    相关文章:

    c# - 是否可以复制具有相似字段的类型实例?

    cuda - 何时将 volatile 与寄存器/局部变量一起使用

    c# - lock 语句中还需要 volatile 吗?

    java - 在什么情况下需要将 volatile 关键字与 Atomic 字段一起使用?

    C#/.NET 动态调用方法的最佳性能方式

    c# - Windows 商店应用程序中是否有等效的 AppDomain.AssemblyResolve?

    .net - ESP8266 - .Net 可行吗?

    安卓同步API?

    java - BidiMap 同步

    Eclipse/Aptana 文件同步解决方案