Volatile Violates its main job?

前端 未结 3 1180
栀梦
栀梦 2020-12-14 17:09

According to MSDN:

The volatile keyword indicates that a field might be modified by multiple threads that are executing at the same time. Fields tha

3条回答
  •  误落风尘
    2020-12-14 17:42

    The MSDN documentation is wrong. That is most certainly not what volatile does. The C# specification tells you exactly what volatile does and getting a "fresh read" or a "committed write" is not one of them. The specification is correct. volatile only guarantees acquire-fences on reads and release-fences on writes. These are defined as below.

    • acquire-fence: A memory barrier in which other reads and writes are not allowed to move before the fence.
    • release-fence: A memory barrier in which other reads and writes are not allowed to move after the fence.

    I will try to explain the table using my arrow notation. A ↓ arrow will mark a volatile read and a ↑ arrow will mark a volatile write. No instruction can move through the arrowhead. Think of the arrowhead as pushing everything away.

    In the following analysis I will use to variables; x and y. I will also assume that they are marked as volatile.

    Case #1

    Notice how the placement of the arrow after the read of x prevents the read of y from moving up. Also notice that the volatility of y is irrelevant in this case.

    var localx = x;
    ↓
    var localy = y;
    ↓
    

    Case #2

    Notice how the placement of the arrow after the read of x prevents the write to y from moving up. Also notice that the volatility of either of x or y, but not both, could have been omitted in this case.

    var localx = x;
    ↓
    ↑
    y = 1;
    

    Case #3

    Notice how the placement of the arrow before the write to y prevents the write to x from moving down. Notice that the volatility of x is irrelevant in this case.

    ↑
    x = 1;
    ↑
    y = 2;
    

    Case #4

    Notice that there is no barrier between the write to x and the read of y. Because of this the either the write to x can float down or the read of y can float up. Either movement is valid. This is why the instructions in the write-read case can be swapped.

    ↑
    x = 1;
    var localy = y;
    ↓
    

    Notable Mentions

    It is also important to note that:

    • x86 hardware has volatile semantics on writes.
    • Microsoft's implementation of the CLI (and suspect Mono's as well) has volatile semantics on writes.
    • The ECMA specification does not have volatile semantics on writes.

提交回复
热议问题