zoukankan      html  css  js  c++  java
  • 盲猜原子变量、内存屏障、内存模型、锁之间的关系

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

  • 相关阅读:
    FastDfs
    git入门大全
    Dynamic Compilation and Loading of .NET Objects
    ASP.NET MVC 传递数据 从前台到后台,包括单个对象,多个对象,集合
    Windows系统不同磁盘间的扩容教程
    服务器Windows 2008 R2 安装SQL 2008 R2
    Windows实现内网IPMI端口转发
    FreeBSD 安装过程
    linux安装Zabbix监控
    Linux VPS实用简单安全配置
  • 原文地址:https://www.cnblogs.com/l2017/p/11614545.html
Copyright © 2011-2022 走看看