Reputation: 129
It seems that for CMPXCHG16B to be used, one has to define _STD_ATOMIC_ALWAYS_USE_CMPXCHG16B = 1 so that these instructions are used.
Why is this the default? I would have never found out about this unless I read the whole atomic.h header either.
What other global defines in the STL are there? Is there a list to review so one can reliably be aware of these implementation details?
Upvotes: 4
Views: 543
Reputation: 13699
_STD_ATOMIC_ALWAYS_USE_CMPXCHG16B
was recently introduced in Visual Studio 2019 (the PR)
Visual Studio 2019 still supports older OSes such as Windows Vista, and Windows 7. These OSes can run on old AMD Opteron CPUs that don't have this instruction.
Even if _STD_ATOMIC_ALWAYS_USE_CMPXCHG16B = 0
, there's runtime detection that uses CMPXCHG16B
if it is available. But in this case the instructions is not inlined, and there's also a branch, so it is less efficient than defining _STD_ATOMIC_ALWAYS_USE_CMPXCHG16B = 1
.
Please also note that CMPXCHG16B
is used for atomic_ref
, but not for atomic
due to ABI compatibility. (It was possible to introduce for atomic_ref
, since there was no pre-C++20 atomic_ref
to be ABI-compatible with).
In vNext
version (the next major, ABI breaking version), atomic
should use CMPXCHG16B
as well. There's also hope that old CPUs/OSes support will be dropped, and the use of CMPXCHG16B
would become unconditional. (See https://github.com/microsoft/STL/issues/1151).
I would have never found out about this unless I read the whole atomic.h header either.
What other global defines in the STL are there? Is there a list to review so one can reliably be aware of these implementation details?
I'm afraid there's no comprehensive list, although some are documented.
The excuse for _STD_ATOMIC_ALWAYS_USE_CMPXCHG16B
in particular could be that whole atomic_ref
is not documented, and as C++20 feature it has experimental status in Visual Studio 2019.
Upvotes: 6