Table of Contents
C++11 Atomic1
C++11 Atomic 可简单分为 4 部分:
atomic
类- 对
atomic
类型的操作函数 atomic_flag
类- 内存序列同步相关操作
atomic
类
主要分为四种模板类:
- 基本
std::atomic
template< class T > struct atomic;
- 整形(Integral)的特化
template<> struct atomic<Integral>;
- bool 的特化
template<> struct atomic<bool>;
- 指针的特化
template< class T > struct atomic<T*>;
bool 和 integral 类型:
std::atomic_bool std::atomic<bool> std::atomic_char std::atomic<char> std::atomic_schar std::atomic<signed char> std::atomic_uchar std::atomic<unsigned char> std::atomic_short std::atomic<short> std::atomic_ushort std::atomic<unsigned short> std::atomic_int std::atomic<int> std::atomic_uint std::atomic<unsigned int> std::atomic_long std::atomic<long> std::atomic_ulong std::atomic<unsigned long> std::atomic_llong std::atomic<long long> std::atomic_ullong std::atomic<unsigned long long> std::atomic_char16_t std::atomic<char16_t> std::atomic_char32_t std::atomic<char32_t> std::atomic_wchar_t std::atomic<wchar_t> std::atomic_int8_t std::atomic<std::int8_t> std::atomic_uint8_t std::atomic<std::uint8_t> std::atomic_int16_t std::atomic<std::int16_t> std::atomic_uint16_t std::atomic<std::uint16_t> std::atomic_int32_t std::atomic<std::int32_t> std::atomic_uint32_t std::atomic<std::uint32_t> std::atomic_int64_t std::atomic<std::int64_t> std::atomic_uint64_t std::atomic<std::uint64_t> std::atomic_int_least8_t std::atomic<std::int_least8_t> std::atomic_uint_least8_t std::atomic<std::uint_least8_t> std::atomic_int_least16_t std::atomic<std::int_least16_t> std::atomic_uint_least16_t std::atomic<std::uint_least16_t> std::atomic_int_least32_t std::atomic<std::int_least32_t> std::atomic_uint_least32_t std::atomic<std::uint_least32_t> std::atomic_int_least64_t std::atomic<std::int_least64_t> std::atomic_uint_least64_t std::atomic<std::uint_least64_t> std::atomic_int_fast8_t std::atomic<std::int_fast8_t> std::atomic_uint_fast8_t std::atomic<std::uint_fast8_t> std::atomic_int_fast16_t std::atomic<std::int_fast16_t> std::atomic_uint_fast16_t std::atomic<std::uint_fast16_t> std::atomic_int_fast32_t std::atomic<std::int_fast32_t> std::atomic_uint_fast32_t std::atomic<std::uint_fast32_t> std::atomic_int_fast64_t std::atomic<std::int_fast64_t> std::atomic_uint_fast64_t std::atomic<std::uint_fast64_t> std::atomic_intptr_t std::atomic<std::intptr_t> std::atomic_uintptr_t std::atomic<std::uintptr_t> std::atomic_size_t std::atomic<std::size_t> std::atomic_ptrdiff_t std::atomic<std::ptrdiff_t> std::atomic_intmax_t std::atomic<std::intmax_t> std::atomic_uintmax_t std::atomic<std::uintmax_t>
基本模板类定义:
template < class T > struct atomic { bool is_lock_free() const volatile; bool is_lock_free() const; void store(T, memory_order = memory_order_seq_cst) volatile; void store(T, memory_order = memory_order_seq_cst); T load(memory_order = memory_order_seq_cst) const volatile; T load(memory_order = memory_order_seq_cst) const; operator T() const volatile; operator T() const; T exchange(T, memory_order = memory_order_seq_cst) volatile; T exchange(T, memory_order = memory_order_seq_cst); bool compare_exchange_weak(T &, T, memory_order, memory_order) volatile; bool compare_exchange_weak(T &, T, memory_order, memory_order); bool compare_exchange_strong(T &, T, memory_order, memory_order) volatile; bool compare_exchange_strong(T &, T, memory_order, memory_order); bool compare_exchange_weak(T &, T, memory_order = memory_order_seq_cst) volatile; bool compare_exchange_weak(T &, T, memory_order = memory_order_seq_cst); bool compare_exchange_strong(T &, T, memory_order = memory_order_seq_cst) volatile; bool compare_exchange_strong(T &, T, memory_order = memory_order_seq_cst); atomic() = default; constexpr atomic(T); atomic(const atomic &) = delete; atomic & operator=(const atomic &) = delete; atomic & operator=(const atomic &) volatile = delete; T operator=(T) volatile; T operator=(T); };
Integral 特有的函数:
integral fetch_add(integral, memory_order = memory_order_seq_cst) volatile; integral fetch_add(integral, memory_order = memory_order_seq_cst); integral fetch_sub(integral, memory_order = memory_order_seq_cst) volatile; integral fetch_sub(integral, memory_order = memory_order_seq_cst); integral fetch_and(integral, memory_order = memory_order_seq_cst) volatile; integral fetch_and(integral, memory_order = memory_order_seq_cst); integral fetch_or(integral, memory_order = memory_order_seq_cst) volatile; integral fetch_or(integral, memory_order = memory_order_seq_cst); integral fetch_xor(integral, memory_order = memory_order_seq_cst) volatile; integral fetch_xor(integral, memory_order = memory_order_seq_cst); integral operator++(int) volatile; integral operator++(int); integral operator--(int) volatile; integral operator--(int); integral operator++() volatile; integral operator++(); integral operator--() volatile; integral operator--(); integral operator+=(integral) volatile; integral operator+=(integral); integral operator-=(integral) volatile; integral operator-=(integral); integral operator&=(integral) volatile; integral operator&=(integral); integral operator|=(integral) volatile; integral operator|=(integral); integral operator^=(integral) volatile; integral operator^=(integral);
指针特有的函数
T* fetch_add(ptrdiff_t, memory_order = memory_order_seq_cst) volatile; T* fetch_add(ptrdiff_t, memory_order = memory_order_seq_cst); T* fetch_sub(ptrdiff_t, memory_order = memory_order_seq_cst) volatile; T* fetch_sub(ptrdiff_t, memory_order = memory_order_seq_cst); T* operator=(T*) volatile; T* operator=(T*); T* operator++(int) volatile; T* operator++(int); T* operator--(int) volatile; T* operator--(int); T* operator++() volatile; T* operator++(); T* operator--() volatile; T* operator--(); T* operator+=(ptrdiff_t) volatile; T* operator+=(ptrdiff_t); T* operator-=(ptrdiff_t) volatile; T* operator-=(ptrdiff_t);
atomic
类型的操作函数
除了 atomic
类的成员函数,也提供了对其操作的函数:
atomic_is_lock_free
: checks if the atomic type’s operations are lock-freeatomic_store
andatomic_store_explicit
: atomically replaces the value of the atomic object with a non-atomic argumentatomic_load
andatomic_load_explicit
: atomically obtains the value stored in an atomic objectatomic_exchange
andatomic_exchange_explicit
: atomically replaces the value of the atomic object with non-atomic argument and returns the old value of the atomicatomic_compare_exchange_weak
atomic_compare_exchange_weak_explicit
atomic_compare_exchange_strong
atomic_compare_exchange_strong_explicit
: atomically compares the value of the atomic object with non-atomic argument and performs atomic exchange if equal or atomic load if notatomic_fetch_add
atomic_fetch_add_explicit
: adds a non-atomic value to an atomic object and obtains the previous value of the atomicatomic_fetch_sub
atomic_fetch_sub_explicit
: subtracts a non-atomic value from an atomic object and obtains the previous value of the atomicatomic_fetch_and
atomic_fetch_and_explicit
: replaces the atomic object with the result of logical AND with a non-atomic argument and obtains the previous value of the atomicatomic_fetch_or
atomic_fetch_or_explicit
: replaces the atomic object with the result of logical OR with a non-atomic argument and obtains the previous value of the atomicatomic_fetch_xor
atomic_fetch_xor_explicit
: replaces the atomic object with the result of logical XOR with a non-atomic argument and obtains the previous value of the atomic
atomic_flag
类
atomic_flag
是一种原子布尔类型,不同于 std::atomic<bool>
, 不提供 load
或 store 操作,只支持两种操作, test_and_set
和 clear
。
atomic_flag() noexcept = default; atomic_flag (const atomic_flag&T) = delete;
std::atomic_flag
只有默认构造函数,拷贝构造函数已被禁用. 一般使用
ATOMIC_FLAG_INIT
初始化为 clear 状态.
内存序列同步相关操作
memory_order
: defines memory ordering constraints for the given atomic operationenum memory_order { memory_order_relaxed, memory_order_consume, memory_order_acquire, memory_order_release, memory_order_acq_rel, memory_order_seq_cst };
kill_dependency
: removes the specified object from thestd::memory_order_consume
dependency treeatomic_thread_fence
: Establishes memory synchronization ordering of non-atomic and relaxed atomic accesses, as instructed by order, without an associated atomic operation.atomic_signal_fence
: Establishes memory synchronization ordering of non-atomic and relaxed atomic accesses, as instructed by order, between a thread and a signal handler executed on the same thread. This is equivalent to std::atomic_thread_fence, except no CPU instructions for memory ordering are issued. Only reordering of the instructions by the compiler is suppressed as order instructs.
Memory Model and Order
在浅谈 Memory Reordering中提及编译开发者和处理器制造商遵循的中心内存排序准则是: 不能改变单线程程序的行为. 从而产生了:
- Memory ordering at compile time: 编译优化造成
- Memory ordering at processor time: CPU 允许乱序机器指令优化造成
在多核多线程时代,当多线程共享某一变量时,不同线程对共享变量的读写就应该格外小心,不适当的乱序执行可能导致程序运行错误。所以必须对编译器和 CPU 作出一定的约束才能合理正确地优化你的程序,这个约束就是 内存模型 (Memory Model) .
或者说,程序转化成机器指令执行时并不按照之前的原始代码顺序执行,所以内存模型是程序员、编译器,CPU 之间的准则约束,遵守这一准则约束后,大家各自做优化, 从而尽可能提高程序的性能。
wiki 上的 Memory model给出一个比较抽象的描述: In computing, a memory model describes the interactions of threads through memory and their shared use of the data.
C++11 中规定了 6 种访存次序(Memory Order),如下:
enum memory_order { memory_order_relaxed, memory_order_consume, memory_order_acquire, memory_order_release, memory_order_acq_rel, memory_order_seq_cst };
上面 C++11 Atomic 涉及 memory_order
的接口, 默认值是
std::memory_order_seq_cst
.
可以把上述 6 种访存次序(内存序)分为 3 类,顺序一致性模型
(memory_order_seq_cst
),Acquire-Release 模型
(memory_order_consume
, memory_order_acquire
,
memory_order_release
, memory_order_acq_rel
) 和 Relax 模型
(memory_order_relaxed
).
memory_order_relaxed
: all reorderings are okay2memory_order_acquire
: guarantees that subsequent loads are not moved before the current load or any preceding loads.memory_order_release
: preceding stores are not moved past the current store or any subsequent stores.memory_order_acq_rel
: combines the two previous guarantees.memory_order_consume
: potentially weaker form of memory_order_acquire that enforces ordering of the current load before other operations that are data-dependent on it (for instance, when a load of a pointer is marked memory_order_consume, subsequent operations that dereference this pointer won’t be moved before it (yes, even that is not guaranteed on all platforms!).memory_order_scq_cst
: 是memory_order_acq_rel
的加强版,除了有acq_rel
语义,还保证是sequencially-consistent.
More
- C++ 多线程与内存模型资料汇总
- Herb Sutter 的 talk
- C++ atomics and memory ordering