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

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

  • 专门的非专业的原子成员函数有什么区别?
  • 以下功能有什么区别(如果有的话)?
  • operator =将值存储到原子对象(公共成员函数)vs store (C ++ 11)中使用非原子参数(公共成员函数)原子地替换原子对象的值
  • 运算符T()从原子对象(公共成员函数加载一个值与加载 (C ++ 11)原子地获取原子对象(公共成员函数)的值。
  • 运算符+ = vs fetch_add
  • operator- = vs fetch_sub
  • 运算符&=fetch_and
  • 运算符| = vs fetch_or
  • 运算符^ = vs fetch_xor
  • 将变量声明为原子变量与非原子变量的缺点是什么? 例如, std::atomic<int> x vs int x的缺点是什么? 换句话说,一个原子变量的开销是多少?
  • 哪一个有更多的开销? 一个原子变量,与一个互斥体保护的正常变量?
  • 这是对我的问题的参考。 http://en.cppreference.com/w/cpp/atomic/atomic


    不是专家,但我会尝试:

  • 专业化(对于像int这样的内置类型)包含额外的操作,例如fetch_add 。 非专用表单(用户定义的类型)将不包含这些。
  • operator=返回它的参数, store不。 另外,非运算符允许您指定一个内存顺序。 标准说operator=是根据store来定义的。
  • 同上,尽管它返回的是load值。
  • 同上
  • 同上
  • 同上
  • 同上
  • 同上
  • 同上
  • 他们做不同的事情。 这是未定义的行为,以使用std::atomic_int的方式使用int
  • 你可以假定开销是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_acquirememory_order_acq_rel

    效果:原子替换由对象指向的值,或用此值替换所需的值。 内存根据order的价值受到影响。

    C A::operator=(C desired) volatile noexcept;
    C A::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。


    我不是这方面的专家,但是如果我理解正确,在你的参考文献中的非专业化操作自动完成一件事,加载,存储,替换等。

    专用函数以原子方式执行两件事,即它们修改并返回一个原子对象,使得两个操作都在任何其他线程混淆之前发生。

    链接地址: http://www.djcxy.com/p/26941.html

    上一篇: c++, c++11, std::atomic member functions

    下一篇: volatile variable and atomic operations on Visual C++ x86