我正在尝试使用 C++ 原子变量的 std::atomic<T>::is_always_lock_free
和 std::atomic<T>::is_lock_free
进行实验。
我编写了一个简单的结构体 A
,想知道原子版本的 A
是否是无锁的:
#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;
}
在 x86-64 Linux 上,我使用 g++ 9.4.0 和 C++17 进行编译,输出正常:
b.is_always_lock_free = false
b.is_lock_free = false
然而,我也在我的Mac(ARM64)上使用clang++ 16.0.0编译了它,输出结果很奇怪:
b.is_always_lock_free = true
b.is_lock_free = false
为什么
is_always_lock_free = true
而 is_lock_free = false
?如果它总是可以无锁,为什么 b
不是无锁的?
ldp/stp
(在ARMv8.4上是原子操作)。 - undefined-march=native
选项(在启用了-mcx16
的机器上):GCC7避免内联lock cmpxchg16b
指令,并报告非无锁,是因为它没有预期的读取侧扩展性(read-side scaling),即读者相互竞争。这可能会改变,一旦GCC开始利用Intel最近几年文档化的16字节加载/存储原子性保证,以支持具备AVX功能标志的Intel CPU。更多详情请参考:https://gcc.gnu.org/ml/gcc-patches/2017-01/msg02344.html。 - undefinedis_lock_free
成员函数的返回值与相同类型的is_always_lock_free
的值一致。 - undefinedstd::atomic<T>
的对齐。请注意,is_always_lock_free
对于所有编译单元都是一个常量,并且显然在翻译开始之前由clang确定,但是模块可以使用不同的设置进行编译,在这种特殊情况下(局部变量)不会造成问题。但是,如果这是一个共享变量,可能会有问题。is_lock_free()
是一个函数。我想知道如果变量是全局的并且在其他单元中,结果是否会相同。 - undefinedb.is_always_lock_free
解析为0。https://godbolt.org/z/xP3z54acz - undefined-std=c++20
选项,输出结果为true / false
。Godbolt在这里无法提供帮助,因为它大多数情况下在Linux环境下编译,而这个问题来自于MacOS系统库。 - undefined