I'm experimenting with C++ atomic's std::atomic<T>::is_always_lock_free
and std::atomic<T>::is_lock_free
.
I wrote a simple struct A
and want to know if the atomic version of A
is lock-free:
#include <iostream>
#include <atomic>
using namespace std;
struct A {
int x;
int y;
int z;
};
int main() {
atomic<A> b;
cout << boolalpha;
cout << "b.is_always_lock_free = " << b.is_always_lock_free << endl;
cout << "b.is_lock_free = " << b.is_lock_free() << endl;
return 0;
}
On a x86-64 Linux, I compiled it with g++ 9.4.0 and C++17, the output is normal:
b.is_always_lock_free = false
b.is_lock_free = false
However, I also compiled it with clang++ 16.0.0 on my Mac (ARM64), the output is strange:
b.is_always_lock_free = true
b.is_lock_free = false
Why is_always_lock_free = true
and is_lock_free = false
? If it can always be lock-free, why b
is not lock-free?
ldp/stp
(which is atomic on ARMv8.4). – Mediator-march=native
(on machines with-mcx16
): GCC7 always avoids inlininglock cmpxchg16b
and reports non-lock-free because it doesn't have the expected read-side scaling: readers contend with each other. gcc.gnu.org/ml/gcc-patches/2017-01/msg02344.html . This might perhaps change once GCC starts taking advantage of Intel's 16-byte load/store atomicity guarantees, retroactively documented in the last couple years, for Intel CPUs with the AVX feature flag. – Otooleis_lock_free
member function is consistent with the value ofis_always_lock_free
for the same type. – Siderolitestd::atomic<T>
in this unit, Note thatis_always_lock_free
is a constant for all compile-units and apparently determined by clang before translation starts, but modules can be compiled with different settings, which doesn't cause problem in this particular case (a local variable). But it can, if that's a shared one.is_lock_free()
is a function. I wonder if result would be same if variable would be global and in other unit. – Tympanitesb.is_always_lock_free
resolves to 0. godbolt.org/z/xP3z54acz – Centralize-std=c++20
, the output istrue / false
. Godbolt won't help here because it compiles most things in a Linux environment, and this issue comes from the MacOS system libraries. – Mediator