聊聊内存屏障_内存栅栏

聊聊内存屏障_内存栅栏本文转载自聊聊内存屏障#导语在之前文章聊聊JMM,说到了内存屏障,内存屏障在Java语言实现一致性内存模型上起到了重要的作用,本文我们一起聊一聊内存屏障内存屏障是什么在cpu执行指令的过程中,

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

本文转载自聊聊内存屏障

导语

在之前文章聊聊JMM,说到了内存屏障,内存屏障在Java语言实现一致性内存模型上起到了重要的作用,本文我们一起聊一聊内存屏障

内存屏障是什么

在cpu执行指令的过程中,对于同一个线程中没有数据依赖的指令可以重新排序优化,有数据依赖的指令按照顺序串行执行,来保证单线程程序运行的正确性,同时也提升了CPU的执行效率,合理的利用了CPU等待时间,

在多核CPU的情况下,因为多核CPU上的指令同时执行,如果涉及到共享变量的修改,这种优化会影响多线程运行的正确性,而内存屏障(memory barrier/memory fence)是硬件层面提供的一系列特殊指令,当CPU处理到这些指定时,会做一些特殊的处理,可以使处理器内的内存状态对其它处理器可见,在不同的平台上支持的内存屏障也会有差异。

解答之前的疑问

在之间的文章聊聊缓存一致性协议中,结尾提到一个问题:MESI频繁的消息请求与响应带来的性能问题如何解决?

MESI协议解决了缓存一致性问题,但是频繁的请求与响应,会产生大量的等待时间,请求等待响应的返回之后才能将数据写入高速缓存中,为了避免减少这种性能问题,硬件层面引入了写缓存(store/write buffer)和无效化队列(invalidate queue), 结构如下图

img

写缓冲器(store buffer也称为 write buffer)是处理器内部的一个容量比高速缓存还小的私有高速缓存部件,每个处理器都有自己的写缓冲器,写缓冲器内部包含若干个条目,并且写缓冲器之间是无法直接访问的。引入写缓冲器,使得处理器在执行写操作的时候,写入写缓冲器中,而不需要等待response响应,来减少写操作的延时,在节省的时间内可以执行更多其它指令,从而提高处理器的执行效率。

无效化队列是用处理Invalidate消息的,当该消息被广播到总线上,其它的CPU都在监听此消息,同其它的CPU都要回复一个Invalidate Response消息,这会产生大量的广播事件,所以在引入无效化队列之后,处理器在收到Invalidate消息之后,并不立马删除地址中对应的副本数据(其实是更新缓存行的状态为无效),而是将消息存入无效化队列之后就直接响应Invalidate Response消息了,从而减少了写操作执行处理器的等待时间。

通过写缓冲器和无效化队列的,将消息累积起来,立马响应请求,提高处理器执行效率,然后在特定的时间(写缓冲满之后或者执行到内存屏障 ),批量将写缓冲中的数据写回主存,将无效化队列应用到高速缓存中,但是他们的引入,又带来了内存重排序和可见性问题。

写缓冲器和无效化队列带来的问题

  • 写缓冲器导致StoreLoad重排

  • 写缓冲器导致StoreStore重排

  • 无效化队列导致LoadLoad重排

  • CPU对共享变量的更新,到达写缓冲器中就返回了,这就可能导致其它CPU无法读到共享变量的最新值,因为共享变量的修改还在前一个CPU的写缓冲器中,连高速缓存都没到了, 无法通过MESI协议保证一致性,这个现象就是可见性问题

  • CPU对于Invalidate的请求,到达无效化队列之后就返回了,还没有将高速缓存中的相关副本数据删除,这就可能导致该处理器读了的数据是过时的数据 ,从而导致更新丢失 ,这个现象也可以理解为是可见性问题

    对于上面的问题,用到的就是我们今天的主角,内存屏障

内存屏障分类与作用

在X86平台提供了几种主要的内存屏障

  1. lfence – 加载屏障
  • 清空无效化队列,根据无效化队列中内容的内存地址,将相应处理器上高速缓存中的缓存条件状态置为I,使后续对该地址的读取时,必须发送Read消息,具体过程可参考 聊聊缓存一致性协议
  • 用在读指令前,阻止屏障两边的读指令重排
  1. sfence – 存储屏障:
  • 冲刷写缓冲器中的内容,将写缓冲器中内容的更新应用于高速缓存
  • 用在写指令之后,阻止屏障两边的写指令重排(执行到该屏障时,将对缓存中的条目打标记,标识这些条目需要在该屏障之前提交,当执行到写操作时,检测到写缓冲器中存在被标记的条目,不管写操作对应的条目状态,即使是E,M也不将写操作的数据回写高速缓存,而是写入写缓冲器的方式,使得屏障之间和屏障之后的指令修改都串行在写缓冲器中,来保证其顺序)
  1. mfence – 全能屏障
  • 具备ifence和sfence的能力, 实现是通过加载屏障和存储屏障的成对使用,可以保证写缓冲的内容同步到高速缓存,无效化队列的内容应用到高速缓存,然后再根据缓存一致性协议保证共享数据的一致性
  • 阻止指令重排
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/168228.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 【c#】开机自启动

    【c#】开机自启动【c#】开机自启动

    2022年4月25日
    31
  • 卷积神经网络概念与原理[通俗易懂]

    卷积神经网络概念与原理[通俗易懂]一、卷积神经网络的基本概念受Hubel和Wiesel对猫视觉皮层电生理研究启发,有人提出卷积神经网络(CNN),YannLecun最早将CNN用于手写数字识别并一直保持了其在该问题的霸主地位。近年来卷积神经网络在多个方向持续发力,在语音识别、人脸识别、通用物体识别、运动分析、自然语言处理甚至脑电波分析方面均有突破。卷积神经网络与普通神经网络的区别在于,卷

    2022年6月13日
    29
  • Jetty 与 Tomcat

    Jetty 与 TomcatJetty也是一个“HTTP服务器+Servlet容器Jetty整体架构简单来说,JettyServer就是由多个Connector(连接器)、多个Handler(处理器),以及一个线程池组成。整体结构请看下面这张图。JettyServer可以有多个Connector在不同的端口上监听客户请求。对比一下Tomcat的整体架构,两者非常的相像。区别:第一个区别是Jetty中没有Service的概念,Tomcat中的Service包装了多个连接器和.

    2025年7月6日
    0
  • 【温故而知新】C和C++篇外篇:COleVariant类型「建议收藏」

    【温故而知新】C和C++篇外篇:COleVariant类型「建议收藏」今天在做一个windows平台的小工具顺便熟悉一下windows开发的一些基础知识,在这个过程中,发现了

    2022年7月18日
    12
  • 看完这篇HTTP,跟面试官扯皮就没问题了

    看完这篇HTTP,跟面试官扯皮就没问题了我是一名程序员,我的主要编程语言是Java,我更是一名Web开发人员,所以我必须要了解HTTP,所以本篇文章就来带你从HTTP入门到进阶,看完让你有一种恍然大悟、醍醐灌顶的感觉。最初在有网络之前,我们的电脑都是单机的,单机系统是孤立的,我还记得05年前那会儿家里有个电脑,想打电脑游戏还得两个人在一个电脑上玩儿,及其不方便。我就想为什么家里人不让上网,我的同学xxx家里有网,每…

    2022年5月4日
    49

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号