[英]c++, c++11, std::atomic member functions
我正在尝试使用std :: atomic库。
std::atomic<int> x
vs int x
的缺点是什么? 换句话说,原子变量的开销是多少? 不是专家,但我会尝试:
int
)包含其他操作,如fetch_add
。 非专业表单(用户定义的类型)不包含这些。 operator=
返回其参数, store
不返回。 此外,非运算符允许您指定内存顺序。 标准说operator=
是根据store
定义的。 load
的值。 std::atomic_int
的方式中使用int
是未定义的行为。 int <= std::atomic <= int and std::mutex
,其中<=
表示'减少开销'。 所以它可能比使用互斥锁(特别是对于内置类型)更好,但比int
更糟糕。 专业和非专业原子成员函数之间有什么区别?
从标准(第29.5节)中这些类的概要可以看出,有三组不同的成员函数:
以下功能之间有什么区别(如果有的话)?
operator=
将值存储到原子对象(公共成员函数)vsstore
(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;
要求: order参数不应该是
memory_order_consume
,memory_order_acquire
,也不是memory_order_acq_rel
。效果:以原子方式替换object指向的值,或者替换为desired的值。 内存受到
order
价值的影响。CA::operator=(C desired) volatile noexcept; CA::operator=(C desired) noexcept;
效果:
store(desired)
返回:
desired
非运算符形式是有利的,因为顺序一致性并不总是必需的,并且它可能比其他存储器顺序更昂贵。 通过仔细分析,可以找出正确操作所需的最小保证,并选择一个限制较少的内存排序,为优化器提供更多余地。
将变量声明为原子变量与非原子变量的缺点是什么。 例如,
std::atomic<int> x
vsint x
的缺点是什么? 换句话说,原子变量的开销是多少?
当常规变量足以限制可能的优化次数时使用原子变量,因为原子变量强加了不可分割性和(可能)内存排序的附加约束。
当需要原子变量时使用常规变量可能会引入数据竞争,这会使行为未定义(§1.10/ 21):
程序的执行包含数据竞争,如果它在不同的线程中包含两个冲突的动作,其中至少有一个不是原子的,并且都不会在另一个之前发生。 任何此类数据争用都会导致未定义的行为。
原子变量的开销是实现质量的问题。 理想情况下,当您需要原子操作时,原子变量的开销为零。 当您不需要原子操作时,它可能具有的任何开销都无关紧要:您只需使用常规变量。
哪一个有更多的开销? 一个原子变量,一个受互斥锁保护的正常变量?
原子变量没有理由比由互斥体保护的普通变量具有更多的开销:最坏的情况,原子变量就是这样实现的。 但是原子变量有可能是无锁的,这会减少开销。 可以使用§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。
我不是这方面的专家,但如果我理解正确,你的参考中的非专业操作会自动执行一项操作,加载,存储,替换等。
专门的函数以原子方式执行两项操作,即它们修改然后以这样的方式返回原子对象,使得两个操作在任何其他线程可能混乱之前发生。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.