Subject: Re: [boost] [atomic] Help understanding consume order
From: Andrey Semashev (andrey.semashev_at_[hidden])
Date: 2014-06-03 05:31:22
On Tue, Jun 3, 2014 at 1:38 AM, Giovanni Piero Deretta
[snip a very helpful example]
> This is of course only one (the one that I'm familiar with) of the
> optimizations that can break seemly correct code, but there are others
> (like aggressive expression reduction) that not even require PGO.
I see. So there's basically no way I can protect myself from such code
injection. The problem is further complicated by the fact that not all
code is "mine" in case of atomic<> implementation.
> The authors of the C++ memory model knew about this issue and added quite
> complex rules to prevent the compiler from breaking dependencies. Compilers
> that may perform dependency breaking optimizations, are required to
> preserve consume ordering at function calls boundaries by issuing explicit
> fences and upgrading the consumes to acquires. The alternative would be to
> require whole program compilation which is untenable. Alternatively,
> sprinkling the code carefully with [[carries_dependency]]supposedly can
> prevent the compiler from issuing the fence.
> In practice implementing the required dependency tracking machinery on
> existing compilers has proven too hard so they issue the fence immediately
> when performing the initial load, so it is possible that the committee will
> change this part of the standard: see N4036 on the last mailing.
N4036 looks interesting, although I suspect adding another type
qualifier to the language has the potential to break code, which now
only accounts for const and volatile. This is more specific to C++.
Also, it's not quite clear how atomic.load(consume) could return a
value dep preserving-qualified type but not
> For the time being we are stuck with either load_acquire or very fragile
Ok, so I did in Boost.Atomic. Thank you again for the most helpful comments.