并发编程

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. 一、CI框架(CodeIgniter)简介

    CI是一个非常好用,非常灵活的PHP框架,在官网https://codeigniter.org.cn/ :最新版本3.1.10 版 就可以尽情使用了. 不忘初心,如果您认为这篇文章有价值,认同作者的付 ...

  2. swiper实现匀速无缝滚动

    设置属性 speed:2500,//匀速时间 autoplay: { delay: 0, stopOnLastSlide: false, disableOnInteraction: true, }, ...

  3. vmware桥接模式-无法内网通-克隆机要删除的文件-ssl

    网卡太多自动模式有时候无法正常通信需要绑定外部网卡 rm /etc/udev/rules.d/-persistent-ipoib.rules vmware报错 Microsoft Runtime DL ...

  4. awk 总结

    说明:本文源于“朱双印博客”,原文地址:http://www.zsythink.net/archives/tag/awk awk 命令: 综合: awk功能是对“文本”进行格式化输出,形成报表:awk ...

  5. 2020/1/30 PHP代码审计之CSRF漏洞

    0x00 CSRF漏洞 CSRF(Cross-site request forgery)跨站请求伪造:也被称为"One Click Attack"或者Session Riding, ...

  6. javacv 设置帧率(续)

    前文地址:https://www.cnblogs.com/svenwu/p/9663038.html 前文已经对大多数正常情况可以支持了,但是我最近处理一些公司的视频流,发现一些坑爹的情况 每次给的视 ...

  7. 18 12 29 css background

    background属性 属性解释 background属性是css中应用比较多,且比较重要的一个属性,它是负责给盒子设置背景图片和背景颜色的,background是一个复合属性,它可以分解成如下几个 ...

  8. ZOJ 3299 线段树 离散化

    本来是个很简单的题目,难住我的主要是这么几点 1.它所有的点都是坐标,不是实际的砖块,1,3指的是1-2 2-3的砖块...后来就是用1 代表1-2 ,2代表2-3.....,这样的话,每次读入的数据 ...

  9. Leetcode第1题:两数之和

    给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的 两个 整数.你可以假设每种输入只会对应一个答案.但是,你不能重复利用这个数组中同样的元素.示例:给定 nums ...

  10. 指针数组的初始化和遍历,并且通过for循环方式、函数传参方式进行指针数组的遍历

    /************************************************************************* > File Name: message.c ...