c++,c++11,std::原子成员函数

c++, c++11, std::atomic member functions

本文关键字:成员 函数 std c++ c++11      更新时间:2023-10-16

我正在尝试使用std::原子库。

  1. 专用非专用atomic之间有什么区别成员功能
  2. 以下功能之间有什么区别(如果有的话)
  3. 运算符=将值存储到原子对象(公共成员函数)v.s.存储(C++11)用非原子参数(公共成员功能)原子替换原子对象的值
  4. 运算符T()从原子对象(公共成员函数)加载一个值。加载(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. 将变量声明为原子v.s.a有什么缺点非原子变量。例如std::atomic<int> xint x?换句话说,一个原子变量的开销是多少
  11. 哪一个开销更大?一个原子变量,v.s.一个法线受互斥锁保护的变量

这是对我的难题的参考。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=将值存储到原子对象(公共成员函数)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_acquirememory_order_acq_rel

效果:用所需的值原子替换对象或this指向的值。根据CCD_ 20的值。

C A::operator=(C desired) volatile noexcept;
C A::operator=(C desired) noexcept;

效果:store(desired)

返回:desired

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

将一个变量声明为原子变量与将其声明为非原子变量的缺点是什么。例如,std::atomic<int> xint x的缺点是什么?换句话说,一个原子变量的开销是多少?

在常规变量足够的情况下使用原子变量会限制可能的优化数量,因为原子变量会对不可分割性和(可能)内存排序施加额外的约束。

当需要原子变量时使用正则变量可能会引入数据竞争,这会使行为不明确(§1.10/21):

如果程序的执行在不同的线程中包含两个冲突的操作,其中至少一个操作不是原子操作,并且在另一个操作之前都没有发生,则程序的执行包含数据竞赛。任何这样的数据竞赛都会导致未定义的行为。

原子变量的开销是实现质量的问题。理想情况下,当您需要原子操作时,原子变量的开销为零。当您不需要原子操作时,它可能产生的任何开销都无关紧要:您只需要使用一个正则变量。

哪一个开销更大?一个原子变量,v.s.一个受互斥锁保护的正常变量?

原子变量没有理由比受互斥体保护的普通变量有更多的开销:在最坏的情况下,原子变量就是这样实现的。但原子变量有可能是无锁的,这将减少开销。该特性可通过§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。

我不是这方面的专家,但如果我正确理解您参考资料中的非专业化操作,可以原子化地做一件事,加载、存储、替换等。

专用函数以原子的方式做两件事,即它们修改然后返回原子对象,这样两个操作都会在任何其他线程处理它们之前发生。