并发编程

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. java中的字符串String

    一.String简介d 参考:https://www.cnblogs.com/zhangyinhua/p/7689974.html String类代表字符串. java.lang.String: Ja ...

  2. 三十一、CI框架之使用验证码

    一.CI的验证码功能用着很是舒服,需要在根目录下新建一个captcha的验证码文件夹用于存放生产的图片,代码如下: 二.浏览器效果如下: 总结:关于验证码生产函数,有很多参数可以设置,包括字体,验证码 ...

  3. Swift实现iOS录音与播放音频功能

    作用AVPLayer:可以用来播放在线及本地音视频AVAudioSession:音频会话,主要用来管理音频设置与硬件交互使用时需要导入 #import <AVFoundation/AVFound ...

  4. “设计型web前端与开发型web前端”有哪些区别?

    学web前端,你弄懂开发型web前端和设计型web前端的区别了吗?今天给大家梳理一下设计型web前端做什么?都要学习什么? 想必大家也会遇到这种情况,要做一个项目,产品经理说产品原型图已经画好了,让我 ...

  5. iOS如何禁用长按页面弹出菜单

    iOS如何禁止用户长按页面导致弹出菜单? 给元素设置样式: -webkit-touch-callout:none; 补充:同样适用于图片如果想禁止用户保存或者复制等

  6. Oracle专题

    定时任务:JOB文件夹 监视执行过的SQL 语句 select * from v$sqlarea a where module='PL/SQL Developer' order by a.FIRST_ ...

  7. NoSQL:

    NoSQL:NoSQL(NoSQL = Not Only SQL ),意即"不仅仅是SQL". 在现代的计算系统上每天网络上都会产生庞大的数据量. 这些数据有很大一部分是由关系数据 ...

  8. ubuntu16+caffe fast-rcnnCPU运行步骤

    //////////////////////////////////////////////////////////////////////////////////////////////////// ...

  9. struct寻址&for反汇编

    //for 反汇编 #include<stdio.h> int main() { ; ; ;i<;i++) { s=s+; } s=; ;i>=;i--) { s=s+; } ...

  10. CodeForces 1000C Covered Points Count(区间线段覆盖问题,差分)

    https://codeforces.com/problemset/problem/1000/C 题意: 有n个线段,覆盖[li,ri],最后依次输出覆盖层数为1~n的点的个数. 思路: 区间线段覆盖 ...