聊聊内存屏障_内存栅栏

聊聊内存屏障_内存栅栏本文转载自聊聊内存屏障#导语在之前文章聊聊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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • leetcode 三数之和_leetcode数组

    leetcode 三数之和_leetcode数组原题链接给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。注意:答案中不可以包含重复的三元组。示例 1:输入:nums = [-1,0,1,2,-1,-4]输出:[[-1,-1,2],[-1,0,1]]示例 2:输入:nums = []输出:[]示例 3:输入:nums = [0]输出:[] 提示:0 <= nums.length <= 300

    2022年8月9日
    1
  • typedef的用法及构造函数的用法

    typedef的用法及构造函数的用法

    2021年9月28日
    47
  • Python 第三方模块 科学计算 SciPy模块1 简介,常数,IO「建议收藏」

    Python 第三方模块 科学计算 SciPy模块1 简介,常数,IO「建议收藏」一.介绍1.介绍:SciPy是1个Python开源库,在BSD授权下发布,主要用于数学/科学/工程计算.SciPy依赖于NumPy来提供方便快速的n维数组操作.组合使用NumPy+SciPy+Matplotlib可以在很大程度上替代MATLAB,并且功能更强大,编程更容易…

    2022年6月28日
    29
  • 海量数据处理的 Top K相关问题「建议收藏」

    海量数据处理的 Top K相关问题「建议收藏」Top-k的最小堆解决方法问题描述:有N(N&gt;&gt;10000)个整数,求出其中的前K个最大的数。(称作Topk或者Top10)问题分析:由于(1)输入的大量数据;(2)只要前K个,对整个输入数据的保存和排序是相当的不可取的。可以利用数据结构的最小堆来处理该问题。最小堆如图所示,对于每个非叶子节点的数值,一定不大于孩子节点的数值。这样可用含有K个节点的最小堆来保存K个目前的最大值(当然根节点是其中的

    2022年6月23日
    35
  • python运算符优先级_excel运算符优先级最高的

    python运算符优先级_excel运算符优先级最高的在Python中,支持以下类型的运算符:算术运算符 比较(关系)运算符 逻辑(布尔)运算符 位运算符 赋值运算符 成员运算符 身份运算符1.算术运算符运算符 含义 示例 + 加:两个对象相加,或者一元加 x+y – 减:两个对象相减,或得到负数 x-y * 乘:两个操作数相乘,或是返回一个被重复若干次的字符串…

    2025年8月6日
    2
  • 海贼王革命家—龙—实力到底如何?[通俗易懂]

    海贼王革命家—龙—实力到底如何?[通俗易懂]龙——整个海贼王世界中最神秘的人物,令世界政府最担心的存在,是所有迷最为期待的实力展现,他的身上好像有着无数的秘密等着尾田为我们揭晓。路飞的父亲——未来的海贼王、卡普的儿子——海军英雄、革民军首领—

    2022年8月5日
    7

发表回复

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

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