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


    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、内存模型由内存屏障体现

  • 相关阅读:
    20190211 模拟训练 A. 大猫咪
    如何诊断节点重启问题
    诊断 Grid Infrastructure 启动问题 (文档 ID 1623340.1)
    bzoj4025 二分图
    root.sh脚本支持checkpoints文件实现重复运行
    [IOI2018] seats 排座位
    最常见的 5 个导致节点重新启动、驱逐或 CRS 意外重启的问题 (文档 ID 1524455.1)
    [IOI2018] werewolf 狼人
    OCR/Vote disk 维护操作: (添加/删除/替换/移动) (文档 ID 1674859.1)
    [POI2011]ROT-Tree Rotations
  • 原文地址:https://www.cnblogs.com/l2017/p/11614545.html
Copyright © 2020-2023  润新知