盲猜原子变量、内存屏障、内存模型、锁之间的关系

1、atomic_flag 和atomic<>的区别,atomic_flag 无论无锁是多大代价(一些cpu可能无锁代价大),都保证atomic_flag 是无锁的。atomic<>会视情况,可能是有锁的也可能是无锁的,哪个开销小选哪个。

2、C++内存模型可以被看作是C++程序和计算机系统(包括编译器,多核CPU等可能对程序进行乱序优化的软硬件)之间的契约,它规定了多个线程访问同一个内存地址时的语义,以及某个线程对内存地址的更新何时能被其它线程看见。C++11 中的 atomic library 中定义了以下6种语义来对内存操作的行为进行约定,这些语义分别规定了不同的重排规则(即插入内存屏障的规则,作为同步点在线程之间同步)。虽然共有 6 个选项,但它们表示的是三种内存模型:

  • sequential consistent(memory_order_seq_cst),
  • relaxed(memory_order_seq_cst).
  • acquire release(memory_order_consume, memory_order_acquire, memory_order_release, memory_order_acq_rel),
typedef enum memory_order {
    memory_order_relaxed,   // relaxed 用于读操作/写操作
    memory_order_consume,   // consume 用于读操作
    memory_order_acquire,   // acquire 用于读操作
    memory_order_release,   // release 用于写操作
    memory_order_acq_rel,   // 相当于acquire和release 
    memory_order_seq_cst    // sequentially consistent 用于读操作/写操作
} memory_order;


memory_order_relaxed 只要求在同一线程中,对同一原子变量的访问不可以被重排,不插内存屏障,最宽松。
memory_order_acquire 和 memory_order_release 是一对的,memory_order_acq_rel同时包括这一对,原子变量写之后的所有写操作才能执行,原子变量读之前的所有读操作都会执行好,
memory_order_consume 原子变量读之前的相关具有依赖性的数据的读操作都会执行好
memory_order_seq_cst 最严格。严格按照顺序来

  

mscv简化了区别

memory_order_relaxed:
void Store_relaxed_4(volatile _Uint4_t *_Tgt, _Uint4_t _Value)
{	
        __iso_volatile_store32((volatile int *)_Tgt, _Value);
}
memory_order_release:
void Store_release_4(volatile _Uint4_t *_Tgt, _Uint4_t _Value)
{
        _Memory_barrier();
        __iso_volatile_store32((volatile int *)_Tgt, _Value);
}
memory_order_seq_cst:
void Store_seq_cst_4(volatile _Uint4_t *_Tgt, _Uint4_t _Value)
{
        _Memory_barrier();
        _iso_volatile_store32((volatile int *)_Tgt, _Value);
	_Memory_barrier();
}          
memory_order_relaxed:
_Uint4_t Load_relaxed_4(volatile _Uint4_t *_Tgt)
{
    _Uint4_t _Value;
    _Value = __iso_volatile_load32((volatile int *)_Tgt);
    return (_Value);
}

memory_order_consume:
memory_order_acquire:
memory_order_seq_cst:
inline _Uint4_t _Load_seq_cst_4(volatile _Uint4_t *_Tgt)
{	
    _Uint4_t _Value;
    _Value = __iso_volatile_load32((volatile int *)_Tgt);
    _Memory_barrier();
    return (_Value);
}

3、个人理解,锁由原子变量和内存屏障实现,原子变量和内存屏障是硬件支持的。

4、如果直接使用锁来保护数据,则不用考虑内存模型,但如果使用原子变量、无锁算法追求更高的性能,则需要考虑好内存模型。

5、内存模型由内存屏障体现

原文地址:https://www.cnblogs.com/l2017/p/11614545.html