首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么std::atomic<T>::is_lock_free()不像常量一样是静态的?

为什么std::atomic<T>::is_lock_free()不像常量一样是静态的?
EN

Stack Overflow用户
提问于 2019-11-12 18:00:50
回答 4查看 749关注 0票数 10

谁能告诉我std::atomic<T>::is_lock_free()是不是像常量一样是静态的?让它是非静态的和/或非常量表达式对我来说没有任何意义。

为什么它一开始就没有像C++17's is_always_lock_free那样设计?

EN

回答 4

Stack Overflow用户

发布于 2019-11-12 18:06:12

正如cppreference上所解释的

除了std::atomic_flag之外,所有的原子类型都可以使用互斥锁或其他锁定操作来实现,而不是使用无锁的

原子指令。原子类型有时也可以是无锁的,例如,如果只有对齐的内存访问在给定的体系结构上自然是原子的,那么相同类型的未对齐的对象就必须使用锁。

C++标准建议(但不要求)无锁原子操作也是无地址的,即适用于使用共享内存的进程之间的通信。

正如其他许多人所提到的,std::is_always_lock_free可能就是您真正想要的。

编辑:为了澄清,C++对象类型有一个对齐值,该值将其实例的地址限制为只能是2的幂的特定倍数([basic.align])。这些对齐值是由实现为基础类型定义的,不需要等于类型的大小。它们也可以比硬件实际支持的更严格。

例如,x86 (主要)支持未对齐的访问。然而,你会发现大多数编译器都有针对x86的alignof(double) == sizeof(double) == 8,因为未对齐的访问有很多缺点(速度、缓存、原子性...)。但是例如#pragma pack(1) struct X { char a; double b; };alignas(1) double x;允许你有“未对齐的”double,所以当cppreference谈到“对齐的内存访问”时,它大概是根据硬件类型的自然对齐来这样做的,而不是以一种与其对齐要求相矛盾的方式使用C++类型(可能是UB)。

这里有更多信息:What's the actual effect of successful unaligned accesses on x86?

也请查看下面@Peter Cordes的有洞察力的评论!

票数 10
EN

Stack Overflow用户

发布于 2019-11-12 18:05:27

您可以使用std::is_always_lock_free

is_lock_free依赖于实际的系统,不能在编译时确定。

相关解释:

原子类型有时也可以是无锁的,例如,如果只有对齐的内存访问在给定的体系结构上自然是原子的,那么相同类型的未对齐的对象就必须使用锁。

票数 3
EN

Stack Overflow用户

发布于 2019-11-12 21:30:39

我已经在我的Windows-PC上安装了Visual Studio 2019,这个devenv也有一个ARMv8编译器。ARMv8允许未对齐的访问,但比较和交换、锁定添加等必须是对齐的。此外,使用ldpstp (32位寄存器的加载对或存储对)的纯加载/纯存储只有在它们自然对齐时才能保证是原子的。

因此,我编写了一个小程序来检查任意原子指针的is_lock_free()返回的值。下面是代码:

代码语言:javascript
复制
#include <atomic>
#include <cstddef>

using namespace std;

bool isLockFreeAtomic( atomic<uint64_t> *a64 )
{
    return a64->is_lock_free();
}

这是isLockFreeAtomic的反汇编

代码语言:javascript
复制
|?isLockFreeAtomic@@YA_NPAU?$atomic@_K@std@@@Z| PROC
    movs        r0,#1
    bx          lr
ENDP

这只是returns true,又名1

此实现选择使用alignof( atomic<int64_t> ) == 8,因此每个atomic<int64_t>都正确对齐。这避免了对每个加载和存储进行运行时对齐检查的需要。

(编者按:这很常见;大多数现实生活中的C++实现都是这样工作的。这就是std::is_always_lock_free如此有用的原因:因为它通常适用于is_lock_free()为真的类型。)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58816223

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档