Is there in WinAPI, POSIX, or in other extensions of API-OS equivalents to all levels of memory barriers from C++11?

StackOverflow https://stackoverflow.com/questions/18571740

Question

Is there in WinAPI, POSIX, or in other extensions of API-OS equivalents to all levels of memory barriers from C++11 std::memory_order, which define the limits on the optimization when reordering operations by the compiler and processor pipeline?

enum memory_order {
    memory_order_relaxed,
    memory_order_consume,
    memory_order_acquire,
    memory_order_release,
    memory_order_acq_rel,
    memory_order_seq_cst
};

ADDITION: An example in WinAPI is present MemoryBarrier(), but it is only equivalents to std::atomic_thread_fence( std::memory_order_seq_cst );. Because Windows mostly works on x86-systems, where plain loads have acquire semantics and plain stores have release semantics: http://www.stdthread.co.uk/forum/index.php?topic=72.0

But, even if the cache L3 (LLC) and the pipeline of x86 cancels reordering optimizations for the load() and store() in accordance with these semantics - std::memory_order_acquire/std::memory_order_release need also to disable compiler optimizations.

It is present in WinAPI:

The _ReadBarrier, _WriteBarrier, and _ReadWriteBarrier compiler intrinsics prevent only compiler re-ordering. To prevent the CPU from re-ordering read and write operations, use the MemoryBarrier macro.

There are in GCC built-in functions for memory model aware atomic operations:

__ATOMIC_RELAXED No barriers or synchronization.

__ATOMIC_CONSUME Data dependency only for both barrier and synchronization with another thread.

__ATOMIC_ACQUIRE Barrier to hoisting of code and synchronizes with release (or stronger) semantic stores from another thread.

__ATOMIC_RELEASE Barrier to sinking of code and synchronizes with acquire (or stronger) semantic loads from another thread.

__ATOMIC_ACQ_REL Full barrier in both directions and synchronizes with acquire loads and release stores in another thread.

__ATOMIC_SEQ_CST Full barrier in both directions and synchronizes with acquire loads and release stores in all threads.

And can I disable this compiler optimizations by using POSIX?

Was it helpful?

Solution

Generally not part of the API standards, but available as intrinsics in most compilers in one form or another.

For example, Visual Studio compilers have _ReadBarrier, _ReadWriteBarrier and _WriteBarrier. (I only linked one, as there are links from that page to the rest. And no, these are not all the levels you have listed - but they are all the levels that x86 has... The list in std::memory_order covers a bunch of other architectures too. [And obvioously memory_order_relaxed is "nothing"].

GCC has a different type of builtin functionality described here, which is aimed at supplying atomic updates, rather than specifically barriers.

However, in general, I would leave it to the compiler/OS to deal with atomic things - use std::atomic<> and similar.

OTHER TIPS

Almost certainly not. The goal of the standard was to cover all eventualities; you specify the minimum that you need, and the compiler provides the minimum in its environment which meets the requirements.

As for compiler optimizations: I suppose that a compiler could evaluate these arguments to the atomic functions, and make optimization dependent on it, but I rather suspect that most compilers will use a much simpler rule: no reordering of memory accesses (at the compiler level) accross accesses to an atomic type.

And I'm not sure what compiler optimizations you want to disable. If the compiler is Posix compliant, it will disable all reordering of memory accesses accross any of the pthread_... functions; and probably accross all system functions. (Imagine if it reordered a write to the buffer after the call to write, or a read from a buffer before the call to read.)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top