并发编程

memory barrier (内存栅栏)

CPU级
1.CPU中有多条流水线,执行代码时,会并行进行执行代码,所以CPU需要把程序指令 分配给每个流水线去分别执行,这个就是乱序执行;
2.CPU中有read buffer/ write buffer 这2个读写缓存,这2个部件用于缓存CPU对内存的读写操作,并不是实时同步到CPU缓存(L1/L2/L3),这个就会导致更新一块内存后,其他CPU感知不到;
读取的时候,优先到read buffer找数据,找到了,就用这个数据了,如果这时内存中的这个数据 已经被更新了,那读取的数据 就是过期数据;这读、写不及时问题,统一称为 数据不一致。

以上2个问题,统称为memory barrier

注意:数据只要到了CPU cache(L1/L2/L3)中,其他CPU都能感知到,只要写数据时,保证写到cache中就行

针对上面2个问题,CPU提供了 memory barrier 相关指令来解决这2个问题
下面用X86 CPU来讲解一下

sfence
这个是"写栅栏"命令,具体语意是:
1.刷新write buffer,把缓存的写操作 都刷到CPU cache中,保证其他CPU能感知到
2.指令乱序保证。
sfence 这个指令 前面的所有写指令 和 后面的所有写指令 是按顺序执行的
(这里的顺序是块的顺序,比如之前有 1 2 3 三条写指令,之后有 4 5 6三条写指令,
保证 1 2 3 肯定比4 5 6中任何一条 执行的早,4 5 6这3条指令,肯定比任何 1 2 3中任何一条执行的晚,至于 1 2 3这三条指令的顺序,就随CPU来决定了)
lfence
这个是"读栅栏"命令,具体语意是:
1.清空read buffer,清空相应的寄存器,保证后续的读操作 到缓存中读取数据,这样才能感知到其他CPU的写动作
2.指令乱序保证。
lfence 这个指令 前面的所有读指令 和 后面的所有读指令 是按顺序执行的
(这里的顺序是块的顺序,比如之前有 1 2 3 三条读指令,之后有 4 5 6三条读指令,
保证 1 2 3 肯定比4 5 6中任何一条 执行的早,4 5 6这3条指令,肯定比任何 1 2 3中任何一条执行的晚,至于 1 2 3这三条指令的顺序,就随CPU来决定了)
mfence
这个是"读/写栅栏"命令,具体语意是:
1.清空read buffer,清空相应的寄存器,刷新write buffer,保证后续的读操作 到缓存中读取数据,这样才能感知到其他CPU的写动作,同时保证写的数据 能被其他CPU感知到
2.指令乱序保证。
mfence 这个指令 前面的所有读/写指令 和 后面的所有读/写指令 是按顺序执行的
(这里的顺序是块的顺序,比如之前有 1 2 3 三条读/写指令,之后有 4 5 6三条读/写指令,
保证 1 2 3 肯定比4 5 6中任何一条 执行的早,4 5 6这3条指令,肯定比任何 1 2 3中任何一条执行的晚,至于 1 2 3这三条指令的顺序,就随CPU来决定了)

编译器级

就是编译参数,部分限制编译器的优化,保证编译出的指令顺序,还有就是在指令队列中插入相应的CPU memory barrier相关指令,等CPU执行指令时,控制CPU的memory barrier行为

编程影响

volatile 这个变量,有memory barrier语意,这个是编译器保证的,在访问volatile变量时,编译器在访问前后 自动插入相关的 memory barrier指令,
JAVA编译在访问volatile变量之前,插入 lfence,在写入volatile变量之后,插入sfence,保证内存可见性

再有就是编译器的相关编译宏(C++)

memory barrier 内存栅栏 并发编程的更多相关文章

  1. 【Java并发编程】6、volatile关键字解析&内存模型&并发编程中三概念

    volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在Java 5之后,volatile关键字才得以 ...

  2. volatile关键字解析&内存模型&并发编程中三概念

    原文链接: http://www.cnblogs.com/dolphin0520/p/3920373.html volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java5之前,它是一个 ...

  3. memory barrier 内存屏障 编译器导致的乱序

    小结: 1. 很多时候,编译器和 CPU 引起内存乱序访问不会带来什么问题,但一些特殊情况下,程序逻辑的正确性依赖于内存访问顺序,这时候内存乱序访问会带来逻辑上的错误, 2. https://gith ...

  4. Java内存模型---并发编程网 - ifeve.com

    Java内存模型 转自:http://ifeve.com/java-memory-model-6/ 原文地址  作者:Jakob Jenkov 译者:张坤 Java内存模型规范了Java虚拟机与计算机 ...

  5. Linux Barrier I/O 实现分析与barrier内存屏蔽 总结

    一直以来.I/O顺序问题一直困扰着我.事实上这个问题是一个比較综合的问题,它涉及的层次比較多,从VFS page cache到I/O调度算法,从i/o子系统到存储外设.而Linux I/O barri ...

  6. [笔记][Java7并发编程实战手冊]系列文件夹

    推荐学习多线程之前要看的书. [笔记][思维导图]读深入理解JAVA内存模型整理的思维导图文章里面的思维导图或则相应的书籍.去看一遍. 能理解为什么并发编程就会出现故障. Java7并发编程实战手冊 ...

  7. Golang并发编程基础

    硬件 内存 作为并发编程一个基础硬件知识储备,首先要说的就是内存了,总的来说在绝大多数情况下把内存的并发增删改查模型搞清楚了其他的基本上也是异曲同工之妙. 内存芯片--即我们所知道的内存颗粒,是一堆M ...

  8. 内存栅栏(memory barrier):解救peterson算法的应用陷阱

    最近一个项目中用到了peterson算法来做临界区的保护,简简单单的十几行代码,就能实现两个线程对临界区的无锁访问,确实很精炼.但是在这不是来分析peterson算法的,在实际应用中发现peterso ...

  9. 【并发编程】一文带你读懂深入理解Java内存模型(面试必备)

    并发编程这一块内容,是高级资深工程师必备知识点,25K起如果不懂并发编程,那基本到顶.但是并发编程内容庞杂,如何系统学习?本专题将会系统讲解并发编程的所有知识点,包括但不限于: 线程通信机制,深入JM ...

随机推荐

  1. ABP .NET CORE 连接mysql

    1.安装mysql程序集,在项目XXX.EntityFrameworkCore下面添加程序集 pomelo.entityframeworkcore.mysql pomelo.entityframewo ...

  2. 腾讯电话面试总结(IEG后台开发)

    1 Java面向对象:设计window画板的类框架.假设现在只有  直线.矩形.椭圆,怎么设计 2 Linux shell命令  定时怎么做 3 平时有问题经常访问那些网站 4 假设你现在是web网站 ...

  3. C++命名规范——谷歌规范

    1.文件命名规则 文件名全部小写,可以含下划线或连字符,按项目约定命名,且尽量保证文件名明确.比如: cmd_save_player_info_class.cc ,my_use_full_class. ...

  4. JSTL 运算符汇总

    算术运算符 + . - . * . / (或 div )和 % (或 mod )  关系运算符 == (或 eq ). != (或 ne ). < (或 lt ). > (或 gt ). ...

  5. Day 4:集合——迭代器与List接口

    Collection-迭代方法 1.toArray()  返回Object类型数据,接收也需要Object对象! Object[] toArray(); Collection c = new Arra ...

  6. idea xml文件去掉背景黄色

    编写dao中的sql时,xml文件中背景一大片黄色,看着不舒服,如何去掉了? 1. File -> Settings... 2. 去消以下两项勾选    (Inspections    -- 如 ...

  7. missing KW_END at ')' near '<EOF>'

    case when 没写 end

  8. UVA - 1631 Locker(密码锁)(dp---记忆化搜索)

    题意:有一个n(n<=1000)位密码锁,每位都是0~9,可以循环旋转.每次可以让1~3个相邻数字同时往上或者往下转一格.输入初始状态和终止状态(长度不超过1000),问最少要转几次. 分析: ...

  9. POJ 2993:Emag eht htiw Em Pleh

    Emag eht htiw Em Pleh Time Limit: 1000MS   Memory Limit: 65536KB   64bit IO Format: %I64d & %I64 ...

  10. JavaScript之HTML DOM Event

    当鼠标在button上点击时,会在button上触发一个click事件.但是button是div的一个子元素, 在button里点击相当于在div里点击,是否click事件也会触发在div上?如果cl ...