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

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

时间: 2024-11-07 07:22:55

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

linux内核同步之每CPU变量、原子操作、内存屏障、自旋锁【转】

转自:http://blog.csdn.net/goodluckwhh/article/details/9005585 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] 一每CPU变量 二原子操作 三优化和内存屏障 四自旋锁 自旋锁 自旋锁的数据结构和宏函数 读写自旋锁 读写自旋锁的相关函数 linux内核中的各种“任务”都能看到内核地址空间,因而它们之间也需要同步和互斥.linux内核支持的同步/互斥手段包括: 技术 功能 作用范围 每CPU变量 为每个CPU复制一份数据

cpu 内存 硬盘 指令以及他们之间的关系

CPU对整个计算机系统的运行是至关重要的,它不仅要与计算机的其他功能部件进行信息交换,还要控制这些功能部件的操作.也就是说cpu是一台计算机的运算核心和控制核心. 内存是与cpu直接交换数据的内部存储器,它可以随时读写,而且速度很快,通常作为操作系统或其他正在运行中的程序的临时数据存储媒介但是内存不能保留数据.当电源关闭时,就会失去数据的储存.如果需要保存数据,就必须把它们写入一个长期的存储设备中,如硬盘. 硬盘采用的持久储存方式,跟内存的区别在于内存断电即失去数据的储存.但是相比较于内存,硬盘

CPU、内存、硬盘、指令之间的关系

1.计算机的组成原理 现代计算机的原型其实最早是由冯·诺伊曼提出的,计算机由五大部分组成:运算器 . 控制器 . 存储器.输入设备.输出设备.其中控制器和运算器又可以统称为CPU   (1)运算器:又称算术逻辑单元,主要是由算术逻辑部件和寄存器组成.用来进行算术或者逻辑运算等操作.主要由指令寄存器.程序计数器.操作数控制器组成. (2)控制器:是整个计算机的控制中心,负责控制和协调整个计算机的动作.能产生各种控制信号,使得各个部件能够一起工作. (3)存储器:存储器是存放计算机信息的一个部件,用

LINUX内核内存屏障

================= ================= By: David Howells <[email protected]> Paul E. McKenney <[email protected]> 译: kouu <[email protected]> 出处: Linux内核文档 -- Documentation/memory-barriers.txt 文件夹: (*) 内存訪问抽象模型. - 操作设备. - 保证. (*) 什么是内存屏障? -

线程同步(1):原子操作,内存屏障,锁综述

原子操作,内存屏障,锁 1.原理:CPU提供了原子操作.关中断.锁内存总线,内存屏障等机制:OS基于这几个CPU硬件机制,就能够实现锁:再基于锁,就能够实现各种各样的同步机制(信号量.消息.Barrier等等等等). 2.所有的同步操作最基础的理论就是原子操作.内存屏障,锁都是为了保证在不同的平台或者是CPU类型下的原子操作. 3.原子操作在单核,单线程/无中断,且编译器不优化的情况下是确定的,是按照C/C++代码顺序执行的,所以不存在异步问题 解释一下这几个知识点为什么会引起异步操作: 首先了

多线程并发编程之原子变量与非阻塞同步机制

1.非阻塞算法 非阻塞算法属于并发算法,它们可以安全地派生它们的线程,不通过锁定派生,而是通过低级的原子性的硬件原生形式 —— 例如比较和交换.非阻塞算法的设计与实现极为困难,但是它们能够提供更好的吞吐率,对生存问题(例如死锁和优先级反转)也能提供更好的防御.使用底层的原子化机器指令取代锁,比如比较并交换(CAS,compare-and-swap). 2.悲观技术 独占锁是一种悲观的技术.它假设最坏的情况发生(如果不加锁,其它线程会破坏对象状态),即使没有发生最坏的情况,仍然用锁保护对象状态.

Java并发编程实战 第15章 原子变量和非阻塞同步机制

非阻塞的同步机制 简单的说,那就是又要实现同步,又不使用锁. 与基于锁的方案相比,非阻塞算法的实现要麻烦的多,但是它的可伸缩性和活跃性上拥有巨大的优势. 实现非阻塞算法的常见方法就是使用volatile语义和原子变量. 硬件对并发的支持 原子变量的产生主要是处理器的支持,最重要的是大多数处理器架构都支持的CAS(比较并交换)指令. 模拟实现AtomicInteger的++操作 首先我们模拟处理器的CAS语法,之所以说模拟,是因为CAS在处理器中是原子操作直接支持的.不需要加锁. public s

cpu,内存,硬盘,指令与他们之间的关系

CPU 内存 硬盘 指令之间的关系 1.CPU: 又称CPU芯片,中央处理器.是计算机上最重要的集成电路,位于计算机的主板上面,其中主要任务是从主存上面提取指令和对指令进行执行. CPU 包括: (1)运算逻辑部件 (2)  寄存器部件    (3) 运算器和控制部件 CPU有大量的引脚,计算机系统通过这些引脚完成通信,这些通信把CPU和本身也是高级电路的存储器与I/O设备链接在一起. 2.内存:又称主存储器,内存储器,其中包含了存储器,MAR,MDR.存储器又包含了存储单元,存储单元又包含存储

个人笔记--内存可见性和原子变量

jdk1.6以后提供了java并发包. volatile与内存可见性: 例子: 结果: 结论: main()线程读取到的td.isFlag并不是true. 这就涉及到了内存可见性问题. 具体原因: 重排序:代码书写的顺序与实际执行的顺序不同. 1.  编译器重排序 2.  指令重排序 3.  内存系统重排序 As-if-serial: 无论如何重排序,程序执行的记过应该与代码顺序执行的结果一致.Java编译器和处理器在运行时都会保证在单线程下遵循这个语言. 补充:jstack可以生成线程快照(j