我正在尝试使用std :: atomic库。
std::atomic<int> x
v.s. int x
?换句话说,原子变量的开销是多少?答案 0 :(得分:10)
不是专家,但我会尝试:
int
)包含其他操作,例如fetch_add
。非专业表格(用户定义的类型)不包含这些。operator=
返回其参数,store
没有。此外,非运算符允许您指定内存顺序。标准说operator=
是根据store
。load
。int
的方式使用std::atomic_int
是未定义的行为。int <= std::atomic <= int and std::mutex
,其中<=
表示“开销较小”。所以它可能比使用互斥锁更好(特别是对于内置类型),但比int
更差。答案 1 :(得分:9)
专业和非专业原子成员函数之间有什么区别?
从标准(§29.5)中这些类的概要可以看出,有三组不同的成员函数:
以下功能之间有什么区别(如果有的话)?
operator=
将值存储到原子对象(公共成员函数)v.s.store
(C ++ 11)用非原子参数(公共成员函数)原子地替换原子对象的值(...)
主要功能差异在于非运算符版本(第29.6.5节,第9-17段及更多)具有额外的参数,用于指定所需的内存排序(第29.3 / 1节)。运算符版本使用顺序一致性内存排序:
void A::store(C desired, memory_order order = memory_order_seq_cst) volatile noexcept; void A::store(C desired, memory_order order = memory_order_seq_cst) noexcept;
要求:订单参数不应为
memory_order_consume
,memory_order_acquire
,也不应为memory_order_acq_rel
。效果:以原子方式替换object指向的值,或者替换为desired的值。内存受到影响 价值
order
。C A::operator=(C desired) volatile noexcept; C A::operator=(C desired) noexcept;
效果:
store(desired)
返回:
desired
非运算符形式是有利的,因为顺序一致性并不总是必需的,并且它可能比其他存储器顺序更昂贵。通过仔细分析,您可以找出正确操作所需的最小保证,并选择一个限制较少的内存排序,为优化器提供更多余地。
将变量声明为原子vs的缺点是什么?非原子变量。例如,
std::atomic<int> x
v。的缺点是什么?int x
?换句话说,原子变量的开销是多少?
当常规变量足以限制可能的优化次数时使用原子变量,因为原子变量强加了不可分割性和(可能)内存排序的附加约束。
当需要原子变量时使用常规变量可能会引入数据竞争,这会导致行为未定义(§1.10/ 21):
程序的执行包含数据竞争,如果它在不同的线程中包含两个冲突的动作,其中至少有一个不是原子的,并且在另一个之前都不会发生。任何此类数据竞争都会导致未定义的行为。
原子变量的开销是实现质量的问题。理想情况下,当您需要原子操作时,原子变量的开销为零。当您不需要原子操作时,它可能具有的任何开销都是无关紧要的:您只需使用常规变量。
哪一个有更多的开销?原子变量,v。由互斥锁保护的正常变量?
原子变量没有理由比由互斥体保护的普通变量有更多的开销:最坏的情况,原子变量就是这样实现的。但是原子变量有可能是无锁的,这会减少开销。可以使用§29.6.5/ 7中标准中描述的功能确定此属性:
bool atomic_is_lock_free(const volatile A *object) noexcept; bool atomic_is_lock_free(const A *object) noexcept; bool A::is_lock_free() const volatile noexcept; bool A::is_lock_free() const noexcept;
返回:如果对象的操作是无锁的,则返回true,否则返回false。
答案 2 :(得分:0)
我不是这方面的专家,但如果我理解正确,您的参考中的非专业操作会以原子方式执行一项操作,加载,存储,替换等。
专门的函数以原子方式执行两项操作,即它们修改然后返回一个原子对象,使得两个操作都发生在任何其他线程可能混乱之前。