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

260*_*607 10 c++ atomic c++11

我正在尝试使用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> xvs 的缺点是 int x什么?换句话说,原子变量的开销是多少?
  11. 哪一个有更多的开销?一个原子变量,一个受互斥锁保护的正常变量?

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

Pub*_*bby 10

不是专家,但我会尝试:

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


R. *_*des 9

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

从标准(第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;
Run Code Online (Sandbox Code Playgroud)

要求:该命令参数不应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;
Run Code Online (Sandbox Code Playgroud)

功效: store(desired)

返回: desired

非运算符形式是有利的,因为顺序一致性并不总是必需的,并且它可能比其他存储器顺序更昂贵.通过仔细分析,可以找出正确操作所需的最小保证,并选择一个限制较少的内存排序,为优化器提供更多余地.

将变量声明为原子变量与非原子变量的缺点是什么.例如,std::atomic<int> xvs 的缺点是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;
Run Code Online (Sandbox Code Playgroud)

返回:如果对象的操作是无锁的,则返回 true,否则返回 false.