lundi 23 avril 2018

Purpose of _Compiler_barrier() on 32bit read

I have been stepping through the function calls that are involved when I assign to an atomic_long type on VS2017 with a 64bit project. I specifically wanted to see what happens when I copy an atomic_long into a none-atomic variable, and if there is any locking around it.

atomic_long ll = 10;
long t2 = ll;

Ultimately it ends up with this call (I've removed some code that was ifdefed out)

inline _Uint4_t _Load_seq_cst_4(volatile _Uint4_t *_Tgt)
    {   /* load from *_Tgt atomically with
            sequentially consistent memory order */
    _Uint4_t _Value;

    _Value = *_Tgt;
    _Compiler_barrier();

    return (_Value);
    }

Now, I've read from MSDN that a plain read of a 32bit value will be atomic:

Simple reads and writes to properly-aligned 32-bit variables are atomic operations.

...which explains why there is no Interlocked function for just reading; only those for changing/comparing. What I'd like to know is what the _Compiler_barrier() bit is doing. This is #defined as

__MACHINE(void _ReadWriteBarrier(void))

...and I've found on MSDN again that this

Limits the compiler optimizations that can reorder memory accesses across the point of the call.

But I don't get this, as there are no other memory accesses apart from the return call; surely the compiler wouldn't move the assignment below that would it?

Can someone please clarify the purpose of this barrier?

Aucun commentaire:

Enregistrer un commentaire