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

时间:2012-03-04 03:45:55

标签: c++ c++11 atomic

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

  1. 专业非专业原子之间的区别是什么 会员职能?
  2. 以下功能之间有什么区别(如果有的话)?
  3. operator = 将值存储到原子对象(公共成员函数)v.s. 存储(C ++ 11)用非原子参数(公共成员函数)原子地替换原子对象的值
  4. 运算符T()从原子对象(公共成员函数)v.s.加载值。 load (C ++ 11)以原子方式获取原子对象的值(公共成员函数)。
  5. 运营商+ = v.s.的 fetch_add
  6. 运营商 - = v.s.的 fetch_sub
  7. 运营商& = v.s.的 fetch_and
  8. 运营商| = v.s.的 fetch_or
  9. 运营商^ = v.s.的 fetch_xor
  10. 将变量声明为原子vs的缺点是什么?一个  非原子变量。例如,有什么不利之处  std::atomic<int> x v.s. int x?换句话说,原子变量的开销是多少?
  11. 哪一个有更多的开销?原子变量,v。一般  变量受互斥锁保护?
  12. 这是我的问题的参考。 http://en.cppreference.com/w/cpp/atomic/atomic

3 个答案:

答案 0 :(得分:10)

不是专家,但我会尝试:

  1. 专精(适用于内置类型,例如int)包含其他操作,例如fetch_add。非专业表格(用户定义的类型)不包含这些。
  2. operator=返回其参数,store没有。此外,非运算符允许您指定内存顺序。标准说operator=是根据store
  3. 定义的
  4. 与上述相同,但它返回load
  5. 的值
  6. 与上述相同
  7. 与上述相同
  8. 与上述相同
  9. 与上述相同
  10. 与上述相同
  11. 与上述相同
  12. 他们做不同的事情。以int的方式使用std::atomic_int是未定义的行为。
  13. 您可以假设开销为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_consumememory_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)

我不是这方面的专家,但如果我理解正确,您的参考中的非专业操作会以原子方式执行一项操作,加载,存储,替换等。

专门的函数以原子方式执行两项操作,即它们修改然后返回一个原子对象,使得两个操作都发生在任何其他线程可能混乱之前。