<atomic>的CMPXCHG16B和MSVC实现不是默认的?
似乎要使用 CMPXCHG16B,必须定义 _STD_ATOMIC_ALWAYS_USE_CMPXCHG16B = 1 以便使用这些指令。
为什么这是默认设置?除非我阅读整个 atomic.h 标头,否则我永远不会发现这一点。
STL 中还有哪些其他全局定义?是否有一份清单可供审查,以便人们能够可靠地了解这些实施细节?
回答
_STD_ATOMIC_ALWAYS_USE_CMPXCHG16B最近在 Visual Studio 2019(PR)中引入
Visual Studio 2019 仍然支持较旧的操作系统,例如 Windows Vista 和 Windows 7。这些操作系统可以在没有此指令的旧 AMD Opteron CPU 上运行。
即使_STD_ATOMIC_ALWAYS_USE_CMPXCHG16B = 0,CMPXCHG16B如果可用,也会使用运行时检测。但在这种情况下,指令不是内联的,而且还有一个分支,所以效率不如定义_STD_ATOMIC_ALWAYS_USE_CMPXCHG16B = 1.
另请注意,CMPXCHG16B用于atomic_ref,但atomic由于 ABI 兼容性而不用于。(可以引入 for atomic_ref,因为没有atomic_ref与 ABI 兼容的 C++20之前的版本)。
在vNext版本(下一个主要的 ABI 破坏版本)中,也atomic应该使用CMPXCHG16B。也希望旧的 CPU/OS 支持将被取消,并且使用CMPXCHG16B将成为无条件的。(参见https://github.com/microsoft/STL/issues/1151)。
除非我阅读整个 atomic.h 标头,否则我永远不会发现这一点。
STL 中还有哪些其他全局定义?是否有一份清单可供审查,以便人们能够可靠地了解这些实施细节?
恐怕没有完整的清单,尽管有些已记录在案。
原因_STD_ATOMIC_ALWAYS_USE_CMPXCHG16B可能是整体atomic_ref没有记录,并且作为 C++20 功能,它在 Visual Studio 2019 中处于实验状态。