Does MS-specific volatility eliminate hardware command reordering

From the documentation :

Microsoft specification

When the / volatile: ms compiler option is used, by default, when non-ARM architectures are targeted, the compiler generates additional code to maintain order among references to mutable objects in addition to maintaining the order of references to other global objects. In particular:

  • Writing to a mutable object (also known as volatile write) has the semantics of Release; i.e. reference to a global or static object
    which occurs before writing to the volatile object in the instruction
    the sequence will occur before this mutable entry in the compiled binary file.
  • Reading a volatile object (also known as mutable reading) has Acquire semantics; i.e. reference to a global or static object
    which occurs after reading volatile memory in the instruction
    the sequence will occur after this volatile read in the compiled binary.

This allows the use of volatile objects for locking and memory releases in multi-threaded applications.

This certainly ensures that volatile does not allow the compiler to reorder compile-time commands (since it explicitly states that the instruction sequence will be the same in the compiled binary ).

But, as we all know, there is such a thing as hardware reordering (for example, a processor can reorder instructions of its own accord). Does volatile provide it as well? I know that synchronization primitives (such as mutexes), but what about MS-specific volatile ?

+5
source share
1 answer

MSDN docs for MS-dependent precarious situation are fully reverting to VS2003. So it was a while - long before std::atomic existed in C ++ 11.

Thus, MS-specific vulnerability, it seems that in previous years the semantics of receive / release was achieved. But now it’s basically out of date, and they left a footnote pushing you away from MS-volatile in favor of std::atomic and /volatile:iso for cross-threading.


As to why they exclude ARM, Microsoft did not build ARM until relatively recently. Besides ARM, they support x86, x64 and Itanium (which is dead).

On x86 and x64, most downloads and repositories already have receive / release semantics (with exceptions such as non-temporary repositories). Therefore, as long as the compiler does not reorder anything, the processor will not * and therefore retains the semantics of receive / release. The /volatile:ms flag instructs the compiler not to reorder, so that receive / release semantics can be achieved on x86 and x64.

Since Microsoft ARM support is relatively new, and MS-dependent volatile ( /volatile:ms ) is deprecated in favor of std::atomic , they probably decided to abandon the classic mutable semantics rather than updating it to work with ARM (which probably would mean the widespread use of memory barriers, given the lack of hardware support).

* The processor will continue to make any changes that it wants, but it will retain the semantics of receiving / releasing the program as long as it is required for x86 / x64. (except in exceptional cases, such as nt stores or clflush). How this happens without disturbing the memory order is another topic.

+7
source