C++11:16 字节原子<>变量是否在 16 字节边界上自动对齐,从而允许CMPXCHG16B指令?
C++11: are 16-byte atomic<> variables automatically aligned on 16-byte boundaries allowing CMPXCHG16B instruction?
16 字节atomic<>
变量是否在 16 字节边界上自动对齐,从而允许编译器/运行时库有效地使用 x86CMPXCHG16B
指令? 还是我们应该始终手动为所有此类变量指定alignas(16)
?
任何像样的std::atomic<>
实现都将使用alignas
本身来使lock cmpxchg16b
高效,如果库完全使用lock cmpxchg16b
而不是 16 字节对象的互斥锁。
并非所有实现都这样做,例如,我认为 MSVC 的标准库使用标准互斥回退使 16 字节对象完全无锁。
你不需要alignas(16)
atomic<T>
.
仅当您有一个要atomic_ref
使用的纯T
对象时,才需要手动对齐原子。atomic_ref<>
没有对齐现有 T 对象的机制。 设计的当前版本公开了应使用的required_alignment
成员。 为了正确性,这取决于你。 (否则,你会得到UB,这可能意味着撕裂,或者只是拆分lock
RMW的极慢的系统范围性能。
// for atomic_ref<T>
alignas(std::atomic_ref<T>::required_alignment) T sometimes_atomic_var;
// often equivalent, and doesn't require checking that atomic_ref<T> is supported
alignas(std::atomic<T>) T sometimes_atomic_var;
// use the same alignment as atomic<T>
请注意,跨缓存行边界的未对齐lock cmpxchg16b
拆分仍然是原子的,但非常非常慢(与任何lock
ed指令相同:原子RMW的原子性保证不取决于对齐(。 更像是实际的总线锁,而不仅仅是延迟MESI响应的本地到此核心缓存锁。
较窄的原子肯定需要自然对齐以确保正确性,因为纯负载和纯存储可以编译为 asm 纯负载或存储,其中硬件保证需要一些对齐。
但是 16 字节对象只能保证原子lock cmpxchg16b
因此.load()
和.store()
必须通过lock cmpxchg16b
来实现。 (使用 CAS(0,0( 加载以获取旧值,然后用自身替换 0 或不执行任何操作,并使用 CAS 重试循环进行存储。 这很糟糕,但比互斥锁好一些。 它没有你期望从无锁load
中获得的读取侧可扩展性,这是GCC7及更高版本不再将atomic<16-byte-object>
宣传为无锁的原因之一,即使它仍将在它调用的libatomic函数中使用lock cmpxchg16b
而不是内联lock cmpxchg16b
- 运行时错误:引用绑定到类型"int"的未对齐地址0xbebebebebebebec6,这需要 4 个字节对齐 (stl_vector.h)
- 为什么 c++ 空类没有字节对齐?
- 为什么动态分配的内存总是16字节对齐
- 使用字节数组具有单字节对齐方式的结构是否安全
- libc++ 的 std::basic_string 的 16 字节对齐模式背后的原因是什么?
- 如何创建 std::vector of char/std::byte,其中第一个字节对齐到 16 个字节,但没有填充
- _declSpec(Align(16))不将指针与16个字节对齐
- 如何迫使新操作员返回的指针将是32字节对齐
- 16字节对齐AAC编码数据
- 正确处理字节对齐问题 - 通过UDP在16位嵌入式系统和32位桌面之间
- c++堆分配默认为32字节对齐
- x86-64上检查指针范围是否跨越N字节对齐地址的最快方法
- 字节对齐与C++中的第三方库冲突
- 位图应该是 2 字节还是 4 字节对齐
- C++ 4 字节对齐的数据
- 如果浮点值是16字节对齐的,是否可以将其直接转换为__m128
- 1字节对齐可能导致内存损坏
- 16 字节对齐问题
- 有没有办法创建一个可以作为参数传递的 16 字节对齐类
- xcode中的对象字节对齐