• .NET:CLR via C# User-Mode Constructs


    The CLR guarantees that reads and writes to variables of the following data types are atomic: Boolean, Char, (S)Byte, (U)Int16, (U)Int32, (U)IntPtr, Single, and reference types. This means that all bytes within that variable are read from or written to all at once.

    Although atomic access to variable guarantees that the read or write happens all at once, it does not guarantee when the read or write will happen due to compiler and CPU optimizations. The primitive user-mode constructs discussed in this section are used to enforce the timing of these atomic read and write operations. In addition, these constructs can also force atomic and timed access to variables of additional data types: (U)Int64 and Double.

    There are two kinds of primitive user-mode thread synchronization constructs:

    • Volatile constructs, which perform an atomic read or write operation on a variable containing a simple data type at a specific time
    • Interlocked constructs, which perform an atomic read and write operation on a variable containing a simple data type at a specific time

    All the volatile and interlocked constructs require you to pass a reference (memory address) to a variable containing a simple data type.

    Volatile Constructs

    Back in the early days of computing, software was written using assembly language. Assembly language is very tedious, because programmers must explicitly state everything—use this CPU register for this, branch to that, call indirect through this other thing, and so on. To simplify programming, CHAPTER 29 Primitive Thread Synchronization Constructs 763 higher-level languages were introduced. These higher-level languages introduced common useful constructs, like if/else, switch/case, various loops, local variables, arguments, virtual method calls, operator overloads, and much more. Ultimately, these language compilers must convert the high-level constructs down to the low-level constructs so that the computer can actually do what you want it to do.

    In other words, the C# compiler translates your C# constructs into Intermediate Language (IL), which is then converted by the just-in-time (JIT) compiler into native CPU instructions, which must then be processed by the CPU itself. In addition, the C# compiler, the JIT compiler, and even the CPU itself can optimize your code.

    The static System.Threading.Volatile class offers two static methods that look like this.

    1 public static class Volatile {
    2   public static void Write(ref Int32 location, Int32 value);
    3   public static Int32 Read(ref Int32 location);
    4 }

    These methods are special. In effect, these methods disable some optimizations usually performed by the C# compiler, the JIT compiler, and the CPU itself. Here’s how the methods work:

    • The Volatile.Write method forces the value in location to be written to at the point of the call. In addition, any earlier program-order loads and stores must occur before the call to Volatile.Write.
    • The Volatile.Read method forces the value in location to be read from at the point of the call. In addition, any later program-order loads and stores must occur after the call to Volatile.Read.

    Important I know that this can be very confusing, so let me summarize it as a simple rule. When threads are communicating with each other via shared memory, write the last value by calling Volatile.Write and read the first value by calling Volatile.Read.

    Interlocked Constructs

    Volatile’s Read method performs an atomic read operation, and its Write method performs an atomic write operation. That is, each method performs either an atomic read operation or an atomic write operation. In this section, we look at the static System.Threading.Interlocked class’s methods. Each of the methods in the Interlocked class performs an atomic read and write operation. In addition, all the Interlocked methods are full memory fences. That is, any variable writes before the call to an Interlocked method execute before the Interlocked method, and any variable reads after the call execute after the call.

  • 相关阅读:
    二维凸包
    luogu_P1287 盒子与球
    luogu_P1993 小K的农场
    luogu_P1712 [NOI2016]区间
    luogu_P2444 [POI2000]病毒
    luogu_P2154 [SDOI2009]虔诚的墓主人
    20191005-T3-U91353 放射性
    编译原理 笔记2 词法分析
    DFA到等价正则表达式的转化
    软件分析笔记10 Soundiness
  • 原文地址:https://www.cnblogs.com/happyframework/p/3430906.html
Copyright © 2020-2023  润新知