C++ 标准::原子<;布尔>;手臂无锁不一致(覆盆子皮3)
我对静态断言有问题。静态断言与此完全相同:C++ 标准::原子<;布尔>;手臂无锁不一致(覆盆子皮3),c++,gcc,raspberry-pi,arm,stdatomic,C++,Gcc,Raspberry Pi,Arm,Stdatomic,我对静态断言有问题。静态断言与此完全相同: static_assert(std::atomic<bool>::is_always_lock_free); 正如你所看到的,它不像CPPPreference网站上所说的那样一致。。。为了比较,我在我的笔记本电脑(Ubuntu 18.04.5)上用g++7.5.0运行了它,得到了: ATOMIC_BOOL_LOCK_FREE --> 2 dummy.is_lock_free() --> true std::atomic_is_
static_assert(std::atomic<bool>::is_always_lock_free);
正如你所看到的,它不像CPPPreference网站上所说的那样一致。。。为了比较,我在我的笔记本电脑(Ubuntu 18.04.5)上用g++7.5.0运行了它,得到了:
ATOMIC_BOOL_LOCK_FREE --> 2
dummy.is_lock_free() --> true
std::atomic_is_lock_free(&dummy) --> true
std::atomic<bool>::is_always_lock_free --> true
ATOMIC\u BOOL\u LOCK\u FREE
(或\u GCC\u ATOMIC\u BOOL\u LOCK\u FREE
)等于1或2有什么区别?在这种情况下,如果1,则它可能是无锁的,如果2,则它是100%无锁的?除了0,还有其他值吗?这是CPPPreference站点上的错误吗?该站点声明所有这些返回值应一致?raspberry pi输出的哪个结果是真的?宏的意思是:
0代码>,用于从不免锁的内置原子类型
用于有时无锁的内置原子类型1
用于始终无锁的内置原子类型2
std::atomic
有时是无锁的,您正在测试的dummy
实例是无锁的,这意味着所有实例都是无锁的
bool std::atomic\u是无锁的(const std::atomic*obj)
:
在任何给定的程序执行中,对于相同类型的所有指针,无锁查询的结果都是相同的
唯一的缺点是,在运行程序之前,您不知道该类型是否无锁
If(not std::atomic_is_lock_free(&dummy)) {
std::cout << "Sorry, the program will be slower than expected\n";
}
If(非std::atomic_是无锁的(&dummy)){
std::cout1
在标准中表示“有时无锁”。但实际上这表示“不知道在编译时是否无锁”。
在没有编译器选项的情况下,GCC的默认基线包括ARM芯片,它们太旧了,不支持原子RMW所需的指令,因此它必须生成可以在古老的CPU上运行的代码,总是调用libatomic函数,而不是内联原子操作
运行时查询函数在带有ARMv7或ARMv8 CPU的RPi上运行时返回true
在-march=native
或-mcpu=cortex-a53
的情况下,您会发现始终是无锁的,因为编译时知道目标机器肯定支持所需的指令。(这些选项告诉GCC生成一个二进制文件,该二进制文件可能不会在其他/旧CPU上运行。)这是正确的
如果没有编译选项,std::atomic
操作必须调用libatomic函数,因此即使在现代CPU上也会有额外的开销
GCC(和所有sane编译器)实现std::atomic
的方式是,它对所有实例都是无锁的,或者没有锁,在运行时不检查每个对象的对齐方式或任何东西
alignof(std::atomic)
为8,即使在32位机器上alignof(int64_t)
仅为4,因此如果原子对象未对齐,这是未定义的行为。(该UB的实际症状可能包括撕裂,即纯加载和纯存储的非原子性。)如果你遵循C++规则,你所有的原子对象都会被对齐;如果你把一个错误的指针抛到<代码>原子*<代码>,并试图使用它,你就只有一个问题。最有可能的是,“有时无锁”意味着“编译时不知道是无锁的”。,但运行时查询函数在使用ARMv7 CPU的RPi上运行后返回true。可能是使用-march=native
或-mcpu=cortex时,无论您得到什么,都是\u始终\u锁定\u自由true
。(如果没有编译选项,std::atomic操作必须调用libatomic
函数,因此即使在现代CPU上也会有额外的开销)实现std::atomic
,它对所有实例都是免锁的,或者没有,不检查每个实例在运行时的对齐方式或任何东西。彼得科德斯:这似乎是合理的。@Rogus你能试试-m
选项看看它是否总是免锁的吗?我在编译中添加了-mcpu=cortex-a53
,它成功了!ATOMIC_BOOL_LOCK_FREE
为2且std::atomic::is_always_LOCK_FREE
计算结果为true
!非常感谢您的帮助!
ATOMIC_BOOL_LOCK_FREE --> 2
dummy.is_lock_free() --> true
std::atomic_is_lock_free(&dummy) --> true
std::atomic<bool>::is_always_lock_free --> true
c++/8/bits/atomic_lockfree_defines.h: #define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE
c++/8/atomic: static constexpr bool is_always_lock_free = ATOMIC_BOOL_LOCK_FREE == 2;
If(not std::atomic_is_lock_free(&dummy)) {
std::cout << "Sorry, the program will be slower than expected\n";
}