繁体   English   中英

c ++,c ++ 11,std :: atomic成员函数

[英]c++, c++11, std::atomic member functions

我正在尝试使用std :: atomic库。

  1. 专业非专业原子成员函数之间有什么区别?
  2. 以下功能之间有什么区别(如果有的话)?
  3. operator =将值存储到原子对象(公共成员函数)vs 存储 (C ++ 11)中,用非原子参数(公共成员函数)原子地替换原子对象的值
  4. operator T()从原子对象(公共成员函数)和load (C ++ 11 加载一个值,原子地获取原子对象的值(公共成员函数)。
  5. operator + = vs fetch_add
  6. operator- = vs fetch_sub
  7. operator&= vs fetch_and
  8. operator | = vs fetch_or
  9. operator ^ = vs fetch_xor
  10. 将变量声明为原子变量与非原子变量的缺点是什么。 例如, std::atomic<int> x vs int x的缺点是什么? 换句话说,原子变量的开销是多少?
  11. 哪一个有更多的开销? 一个原子变量,一个受互斥锁保护的正常变量?

这是我的问题的参考。 http://en.cppreference.com/w/cpp/atomic/atomic

不是专家,但我会尝试:

  1. 特化(对于内置类型,如int )包含其他操作,如fetch_add 非专业表单(用户定义的类型)不包含这些。
  2. operator=返回其参数, store不返回。 此外,非运算符允许您指定内存顺序。 标准说operator=是根据store定义的。
  3. 与上面相同,虽然它返回load的值。
  4. 与上述相同
  5. 与上述相同
  6. 与上述相同
  7. 与上述相同
  8. 与上述相同
  9. 与上述相同
  10. 他们做不同的事情。 在使用std::atomic_int的方式中使用int是未定义的行为。
  11. 您可以假设开销是int <= std::atomic <= int and std::mutex ,其中<=表示'减少开销'。 所以它可能比使用互斥锁(特别是对于内置类型)更好,但比int更糟糕。

专业和非专业原子成员函数之间有什么区别?

从标准(第29.5节)中这些类的概要可以看出,有三组不同的成员函数:

  • 最通用的只提供存储,加载,交换和比较交换操作;
  • 除了通用类型之外,整数类型的特化提供原子算术和按位运算;
  • 指针的特化除了通用指针之外还提供指针算术运算。

以下功能之间有什么区别(如果有的话)?

operator=将值存储到原子对象(公共成员函数)vs 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; 

要求: order参数不应该是memory_order_consumememory_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 vs int 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM