> There is no requirement that an acquire barrier be preceded by a release barrier. All an acquire barrier means is "ensure that no read operation after this instruction can be reordered before this instruction". Similarly, a release barrier means "ensure that all pending write operations are completed before passing beyond this instruction".

This is a common simplification of the memory model but it is incorrect. The standard does not describe things in those terms, it's only concerned with happens-before relationships. The effect of an acquire operation is that if it observes a value from a release sequence headed by a particular release operation then the acquire happens-before the release operation, which through the transitive clause in the definition of happens-before means that all operations preceding the release happen-before all operations succeeding the acquire.

You are maybe correct in an _extremely_ pedantic sense that there's no _explicit_ requirement that an acquire correspond to a release - it just happens to be the case that if you follow the definitions in the standard then an acquire that never observes a value written by a release sequence does not have any semantics different than a relaxed operation.


On 12 June 2026 00:34:14 BST, Simon Cooke <sicooke@google.com> wrote:
There is no requirement that an acquire barrier be preceded by a release barrier. All an acquire barrier means is "ensure that no read operation after this instruction can be reordered before this instruction". Similarly, a release barrier means "ensure that all pending write operations are completed before passing beyond this instruction". 

It's much clearer if you break it out into explicit memory barrier/fence instructions. One thing that's misleading is that the acquire/release naming makes people think "I'm acquiring some data / I'm releasing some data" - which isn't the case. It's named after mutex/critical section behavior - acquiring the lock vs. releasing the lock. 

Acquiring a lock doesn't require you to release a lock before you do it for the first time. 

On Wed, Jun 10, 2026 at 10:37 PM Jennifier Burnett <jenni@jburnett.me.uk> wrote:
An acquire barrier is meaningless in this context. An acquire barrier needs either a release operation or atomic operation preceded by a release barrier to have any semantics beyond relaxed. What exactly would you be establishing a happens-before relationship with in the original example? Assuming the call to now() is an implicit acquire barrier changes nothing about the semantics because there's no corresponding release for it to establish a happens-before relationship with. The first thread doesn't even have any operations other than the call to now() that the acquire barrier would apply to

On 11 June 2026 01:37:42 BST, Thiago Macieira via Std-Discussion <std-discussion@lists.isocpp.org> wrote:
>On Wednesday, 10 June 2026 16:24:30 Pacific Daylight Time Simon Cooke wrote:
>> If you don't want that, you need acquire semantics, which will prevent the
>> write from down after the timestamp() call in #2
>
>This is the essence of the argument: reading from the monotonic clock should
>be an acquire barrier. The Standard does not say it is, but I think it should.
>