目录

处理器协同机制其一缓存一致性协议(MESI)

处理器协同机制其二内存屏障与内存顺序(及Store Buffer与Invalidate Queue)

处理器协同机制其三C++内存顺序与栅栏(及依赖性读屏障)

三、存储缓冲与无效队列

当处理器需要的数据不在其缓存中,需要请求,等待内存或其他缓存来响应,这个过程降低了处理器的工作效率。为此,引入存储缓冲,处理器只需要将修改的内容放入存储缓冲,就可以继续执行了,存储缓冲中的数据会适时地刷新到其缓存中。

存储缓冲的引入,可能会出现数据不一致的情况,为此需要存储转發机制。即处理器读取数据优先从存储缓冲中读取。

同时,存储缓冲引入了存储的乱序,处理器先向存储缓冲写入数据,後向其缓存写入数据,对于另一处理器可能会感知写入顺序正好相反。为了保证写入顺序,应该在其间加入一个指令以标记存储缓冲(有标记的数据,接下来处理器不能直接写入缓存),这样的指令就是写屏障。

引入存储缓冲并不能很好的提高性能,因为存储缓冲容易填满而导致效率降低,主要是因为“使无效消息”的处理速度跟不上。为此,引入无效队列,只要将“使无效消息”放入无效队列就可以回应“认可使无效消息”,在合适的时机处理无效队列中的消息。

于是,处理器的缓存体系结构为:

当然,为了保证一致性,处理器要将發送MESI消息,若无效队列中有相关缓存行的消息则必须等待之後才能进行。这个承诺,在对缓存行的竞争不是很严重的情况下能够成立。

无效队列的引入,也引入了加载的乱序,另一处理器依序修改两个缓存行,某一处理器对“使无效消息”的处理可能是:先收到的“使无效消息”放入无效队列,後收到的直接处理或者没有收到该消息(因为此缓存行被对方独占)。这样一来,该处理器对缓存行的修改顺序的感知可能正好是相反的。为了保证缓存一致性的结果,若无效队列中有相关消息则CPU对缓存行的访问应该等待之後进行,这样也就保证了加载的结果有序,但不保证执行有序。

同样地,处理器發现之後的加载可以直接进行(缓存了有效数据),之前的加载需要等待(需要从其他地方获取),于是加载的执行乱序了。设想,另一CPU先修改S状态缓存行再修改E/M状态缓存行,某CPU由于乱序执行先获取了未修改的S状态缓存行数据再获取传递过来的已修改的另一缓存行,很明显程序逻辑可能是相反的。

读屏障防止上述加载的执行乱序,同时保证加载的结果有序(此为依赖性读屏障的功能)。

四、内存屏障与内存顺序

现代处理器是乱序执行架构,其必须遵守以下规则:(乱序执行原则)

1、每个CPU都认为自己的内存访问按编程顺序进行。

2、仅当两个操作涉及不同的位置时,CPU才会对其存储操作重新排序。

3、某CPU的在读屏障之前的加载先于其任何在读屏障之後的加载被所有CPU所感知。

4、某CPU的在写屏障之前的存储先于其任何在写屏障之後的存储被所有CPU所感知。

5、某CPU在完全屏障之前的内存访问先于其任何在完全屏障之後的访问被所有CPU感知。

内存屏障保证的可见性不能在三个及以上CPU中传递,这种“传递性”需要另一种机制来保证,通常硬件设计者要考虑这种问题。目前所知道的CPU都提供“传递性”。

内存访问重排序的类型:

1、读写重排序

LoadLoad barrier: 取取屏障,阻止其前的加载被重排序到其後的加载之後。

StoreStore barrier: 存存屏障,阻止其前的存储被重排序到其後的存储之後。

LoadStore barrier: 取存屏障,阻止其前的加载被重排序到其後的存储之後。

StoreLoad barrier: 存取屏障,阻止其前的存储被重排序到其後的加载之後。

2、原子操作重排序

Atomic with Loads: 原子指令与加载重排序。

Atomic with Stores: 原子指令与存储重排序。

3、依赖性加载重排序

smp_read_barrier_depends()是依赖性读屏障,当接下来的加载地址需要依赖之前加载的数据计算而得时,就存在数据依赖性。这种屏障在Alpha架构的CPU上存在。

4、指令缓存与指令流水线不一致

这种CPU需要为自修改代码执行特殊指令以保证一致性,例如:条件跳转指令。

带括号的CPU架构表示其支持该模式,但实际很少使用。

Linux内核的内存屏障:

1、smp_mb(): 完全屏障,防止读写重排序,用作“存取屏障”。

2、smp_rmb(): 读屏障,“取取屏障”的语义,同时用作“取存屏障”。

3、smp_wmb(): 写屏障,“存存屏障”的语义。

4、smp_read_barrier_depends(): 依赖性读屏障,通常可用读屏障代替。

5、mmiowb(): MMIO写屏障,用于保证被自旋锁保护的MMIO写入顺序,在某些平台上,自旋锁中的内存屏障已经保证了MMIO的顺序故而此屏障定义为空。这个原语比较新,故而较少驱动使用它。

以上这些原语(在指定平台上不为空)同时阻止了编译器为了优化而对内存访问重排序。同样,在单处理器上也有类似的内存屏障,这通常用于编写驱动。通常,可以不直接使用内存屏障,使用一些互斥原语(自旋锁、互斥锁、信号量等),其隐含了所需的内存屏障。

1、Alpha,独有的依赖性读屏障。

2、AMD64,与x86兼容,强一致性内存模型,某些SSE等指令使用较弱的内存模型,其读屏障指令是lfence,写屏障是sfence,完全屏障是mfence,一般只使用mfence就行。

3、x86,CPU提供处理顺序,因此存储不会乱序,但是,CPU通常不保证加载的顺序,故而加载可以在存储完成前提前执行。x86处理器不一定支持内存屏障(lfence,sfence,mfence),可能用带lock的指令代替之。同时,执行自修改代码之前需要特殊指令(例如跳转指令)。

4、其他架构,此处省略。

处理器协同机制其二内存屏障与内存顺序(及Store Buffer与Invalidate Queue)相关推荐

  1. 处理器协同机制其三C++内存顺序与栅栏(及依赖性读屏障)

    目录 处理器协同机制其一缓存一致性协议(MESI) 处理器协同机制其二内存屏障与内存顺序(及Store Buffer与Invalidate Queue) 处理器协同机制其三C++内存顺序与栅栏(及依赖 ...

  2. 【Linux 内核 内存管理】优化内存屏障 ④ ( 处理器内存屏障 | 八种处理器内存屏障 | 通用内存屏障 | 写内存屏障 | 读内存屏障 | 数据依赖屏障 | 强制性内存屏障 |SMP内存屏障 )

    文章目录 一.处理器内存屏障 二.Linux 内核处理器内存屏障 一.处理器内存屏障 " 处理器内存屏障 " 针对 " CPU " 之间的内存访问乱序 和 CP ...

  3. java内存屏障_内存屏障 | 并发编程网 – ifeve.com

    本文我将和大家讨论并发编程中最基础的一项技术:内存屏障或内存栅栏,也就是让一个CPU处理单元中的内存状态对其它处理单元可见的一项技术. CPU使用了很多优化技术来实现一个目标:CPU执行单元的速度要远 ...

  4. java 什么是内存屏障,java内存屏障和可见性

    内存屏障 由于现代的操作系统都是多处理器.而每一个处理器都有自己的缓存,并且这些缓存并不是实时都与内存发生信息交换.这样就可能出现一个cpu上的缓存数据与另一个cpu上的缓存数据不一致的问题.而这样在 ...

  5. java内存屏障_java内存屏障

    java内存屏障 java的内存屏障通常所谓的四种即LoadLoad,StoreStore,LoadStore,StoreLoad实际上也是上述两种的组合,完成一系列的屏障和数据同步功能. LoadL ...

  6. atomic 内存序_C++内存屏障(内存顺序)总结

    原子操作(atomic)是无锁编程(Lock-Free Programming)的基础.以往,要使用atomic操作,我们一般会使用gcc内置的原子操作接口,或者是基于指定平台硬件指令封装的atomi ...

  7. linux 内存屏障,理解内存屏障(一)

    作者:新浪微博() 计算机学习微信公众号(jsj_xx) 1 前言 内存屏障是搞软件的需要面对的一个涉及硬件cpu的问题,很多人困惑不解.本文是我们对linux内核内存屏障的理解,参考linux内核( ...

  8. 关于缓存一致性协议、MESI、StoreBuffer、InvalidateQueue、内存屏障、Lock指令和JMM的那点事

    前言 事情是这样的,一位读者看了我的一篇文章,不认同我文章里面的观点,于是有了下面的交流. 可能是我发的那个狗头的表情,让这位读者认为我不尊重他.于是,这位读者一气之下把我删掉了,在删好友之前,还叫我 ...

  9. 原子变量、锁、内存屏障,写得非常好!

    突然想聊聊这个话题,是因为知乎上的一个问题多次出现在了我的Timeline里:请问,多个线程可以读一个变量,只有一个线程可以对这个变量进行写,到底要不要加锁?可惜的是很多高票答案语焉不详,甚至有所错漏 ...

最新文章

  1. 零基础如何选择适合的Java培训课程
  2. 使用数字示波器DS6104测量交流信号的幅值和相位
  3. java中javamail收发邮件实现方法
  4. 性别分析--微信数据分析(一)
  5. Nginx Slab内存管理
  6. JavaScript读取本地图片到浏览器
  7. 盲视频超分辨率:南理工提出不用HR参与也能训练的自监督学习方法
  8. php简介的编辑器,推荐几款功能强大的PHP编辑器
  9. shell基础之for循环语句
  10. c语言程序设计实例220,C语言程序设计实例大全(220个例子)
  11. linux中安装yum简单方法
  12. 量子计算机编程教程,量子信息与量子计算简明教程 PDF扫描版[12MB]
  13. 国密算法c语言实现,求 国密sm2 算法 第四部分 公钥加密算法 c语言实现代码,该怎么解决...
  14. 台式电脑主板插线步骤图_电脑主板跳线接法图文教程(安装过程)
  15. 【Squoosh】谷歌开源在线图片压缩工具
  16. 群晖wordpress如何连接mysql,玩转群晖虚拟机:非插件安装WordPress
  17. Wordpress主题制作基础教程
  18. linux pppd源码下载_linux pppd脚本配置(转载)
  19. 跑步机健身器材标准ENISO20957检测范围有哪些
  20. 三栏布局:左右固定,中间自适应的几种方式

热门文章

  1. 金庸小说《倚天》和《神雕》的关系隐晦微妙,中间缺失的八十年里,份量最重的就是郭襄的一生沉浮
  2. Unity3D接入第三方插件之微信登录安卓SDK
  3. tf.clip_by_global_norm详解
  4. mysql组复制(MGR)——背景
  5. 注意力机制在深度推荐算法中的应用之AFM模型
  6. el-date-picker 实现禁止选择今日以后的日期,以及时间跨度不超过365天,和设置默认选择日期,解决选择当天无效问题
  7. java实现简易计算器,实现加减乘除,括号,算式查错,
  8. 仓鼠找sugar II
  9. 通过pdf实现seo
  10. python开发office插件_看完这篇Python操作PPT总结,从此使用Python玩转Office全家桶就没有压力了!...