C++ Logo

std-discussion

Advanced search

Re: Generalized atomic updates

From: Andrey Semashev <andrey.semashev_at_[hidden]>
Date: Thu, 9 May 2024 00:19:27 +0300
On 5/8/24 19:39, Thiago Macieira via Std-Discussion wrote:
> On Tuesday 7 May 2024 22:19:57 GMT-7 Nate Eldredge via Std-Discussion wrote:
>>
>> However, many architectures
>> have load-link/store-conditional instructions (e.g. ARM64 with LDRX/STRX)
>> and could implement this more efficiently by executing f() in between the
>> LL and SC. So in effect, fetch_update would expose the LL/SC
>> functionality for use at the level of C++. It could also be implemented
>> with transactional memory where available.
>
> That's interesting, but f needs to be extremely simple, otherwise that
> machinery can't be used and the store-conditional will always fail. On some
> architectures (and my LL/SC is very rusty), you cannot place function calls
> between the two, so f must be always inlined.

Another example might be no memory access instructions within the LL/SC
pair. Even if they are formally allowed, page faults may get in the way.
Which would make the whole concept extremely unreliable, as the compiler
normally doesn't have those kind of restrictions and e.g. is free to
generate loads from the function object state or bound variables. With
optimizations disabled, the compiler will also generate loads and stores
on the stack for every variable.

I did consider implementing this concept for Boost.Atomic, but
eventually decided that even if I did, the LL/SC instructions would not
be the right backend for it. It would have to be either a CAS loop or
something like x86 RTM. We know RTM is basically dead now, and I'm not
sure there are equivalents on other popular architectures, so we're
basically left with a CAS loop implementation only. This doesn't offer
performance benefits, likely the opposite (because with a proper CAS
loop you can optimize away an extra atomic load), so I dropped the idea.

Received on 2024-05-08 21:19:30