JAVA并发编程之原子性、可见性与有序性

并发编程-原子性、可见性与有序性

一、CPU的可见性

1.1 缓存一致性问题的出现

CPU处理器在处理速度上,远胜于内存,主内存执行一次内存的读写操作,所需要的时间足够处理器去处理上百条指令。

为了弥补处理器与主内存处理能力之间的差距,CPU引入了高级缓存。CPU去主内存拉取数据后,会将数据存储到CPU的高级缓存中,下次如果还涉及到操作这个数据,直接从CPU高速缓存中获取即可,避免了长时间的和主内存操作,对CPU带来的性能损耗。

随着硬件能力不断的提升,现在的CPU都是多核的,而每个CPU内核都有自己的高速缓存。如果主内存中的同一个数据,被多个CPU内核缓存了,如果其中一个内核修改了数据,另一个内核不知道!造成了数据的不一致性。

1.2 CPU的高速缓存模型

image.png

1.3 CPU缓存行

数据在高速缓存中不是以独立项来存储的,他的数据都存储在缓存行中,CacheLine。缓存行是CPU高速缓存的最小存储单位。

目前主流的CPU缓存的缓存行通常是64字节。

比如剖析开高速缓存,里面就是多个缓存行组成滴。

image.png

比如Java中一个long类型是8字节,一个缓存行最多就可以缓存8个Long类型数据。

1.4 MESI协议

并不是所有的CPU都基于MESI协议去制作CPU,但是主流的CPU大多都是基于MESI协议来解决缓存一致性问题的。

M:modify修改了

表示缓存行数据被修改了,并且没有同步到主内存。而且这个数据是当前CPU独占的,其他CPU内核的缓存没有这个数据。

这个状态数据没有安全问题。

E:exclusive独占

表示缓存行数据是独占的,并且这个数据没有被修改,和主内存的数据是一致的。

这个状态数据没有安全问题。

S:shared共享

表示缓存行数据是共享的,这个数据被多个CPU缓存在缓存行中。并且都与内存中的值是一致的。

这个状态数据没有安全问题。

I:invalid无效

表示缓存行的数据是无效的,如果需要使用这个数据,需要重新去主内存拉取(那边同步完)。

1.5 MESI是如何保证缓存一致性

MESI协议对不同的状态增加了不同的 监听任务

  • 一个处于M状态的缓存行,必须时刻监听所有试图读取当前缓存行对应的主内存数据地址的操作。如果坚挺到有其他内核要读取这个数据,必须在读取操作之前先将缓存行数据写回主内存。
  • 一个处于S状态的缓存行,必须时刻监听该缓存行 无效 或者 独占 或者 修改 当前缓存行的请求,如果监听到,将当前缓存行状态设置为I。
  • 一个处于E状态的缓存行,必须时刻监听视图 读取 当前缓存行对应的主内存地址的操作,如果监听到,将当前缓存行状态修改为S。

核心其实在于第一点和第二点。

第一点:可以避免其他线程读取到主内存的脏数据。

第二点:可以将缓存不一致的情况的缓存行设值为无效。

1.6 CPU写优化层面对MESI协议的影响

写缓冲器(StoreBuffer,WriteBuffer)是处理器内部一个容量比L1还笑的一个高速缓存组件,每个CPU内核都有自己的Store Buffer。一些写操作,不会直接执行落到L1缓存上,而是先落到StoreBuffer上,这样CPU可以省去等待响应的时间,减少写操作的延迟,提升CPU的效率。但是这种情况会影响到MESI协议的触发,导致其他缓存行应当变为I状态,但是因为StoreBuffer数据还没落到L1,导致无法触发。

无效化队列(Invalidate Queue),这个东西是处理Invalidate消息的。这个Queue是做优化滴,需要将invalid处理广播给其他的CPU,并且其他CPU需要返回一个response,大量的广播消息需要一定时间的等待response。CPU在做广播时,会将invalid消息扔到无效化队列中,不需要直接响应response消息了,减少了写操作消耗的时间。

上述两种对CPU写操作的优化,会导致MESI协议触发存在延迟甚至无法触发的问题。在CPU层面为了解决这个问题,就需要一个指令,那就是lock指令。

lock前缀指令 期间的写操作,会立即写回主内存,那CPU的高速缓存必然也要写回去,必然会触发MESI协议,让其他缓存行将状态同步。

二、CPU的原子性

CPU的一条指令必然是原子性的。

但是一些其他程序的操作,到了咱们CPU执行层面上,可能会有多个指令。就比如i++,在CPU层面是三条指令:

  • 主内存读取数据
  • 寄存器+1
  • 数据写回主内存

但是对于修改数据而言,还是会因为多核CPU并行处理,导致一些数据安全问题,所以CPU也需要保证原子性的一些操作。就比如CAS指令,这个是CPU支持的原语。

but,CPU支持一个指令叫做cmpxchg,也就是CAS操作,在多核情况下,如果没有保证多核之间的原子性,会导致cmpxchg操作,存在数据安全问题。

So,在多核CPU下,执行cmpxchg指令时,会在前面甩一个lock指令,来保证多核CPU的原子性。

lock指令类似CPU中的锁操作,并且锁操作的粒度有两种。

  • 总线锁:会锁总线,其他所有CPU内核对主内存做读写操作请求时,都会被阻塞住,直到释放总线锁。
  • 缓存锁:因为总线锁效率嘎嘎低,现在的CPU都是采用锁缓存提来锁总线。在没有办法利用缓存所时,会被迫使用总线锁。

Lock前缀指令 在Intel官方的一些文档信息:https://www.felixcloutier.com/x86/lock

三、CPU的有序性

首先要请求,CPU本身会在一定规则下,对一些指令进行重新排序。

比如as-if-serial原则,保证单线程的程序结果不变的情况下,随便重排序。重新排序的目的是为了提升CPU的执行效率,合理的利用CPU的等待时间。

在多核CPU的情况下,因为多核CPU上的指令存在同时指定的情况,如果涉及到临界资源的修改,这种指令重排序会影响多线程运行结果的准确性。

内存屏障(Memory Barrier/Memory fence)是硬件层面提供的一些列的特殊指令,当CPU处理到这些指令时,会做一些特殊的处理,来规避重排序带来的问题。

在×86平台提供了几种比较主要的内存屏障:

  • lfence - 加载屏障
    • 放在读指令之前,阻塞屏障前后的指令重排
  • sfence - 存储屏障
    • 放在写指令之前,阻塞屏障前后的指令重排
  • mfence - 全能屏障
    • 具备了lfence和sfence的两个功能。

https://gee.cs.oswego.edu/dl/jmm/cookbook.html

image.png

mfence最终依然是 lock前缀指令

image.png

四、JMM-Java内存模型

JMM(Java Memory Model)Java内存模型是一个语言级别的内存模型抽象,他屏蔽了底层硬件实现内存一致性需求的差异,提供了对上层的统一的接口来保证内存一致性的编程能力。

Java作为一个跨平台的语言,Java内存模型就是一个中间层模式。他适配不同的底层硬件系统,设计中间层模型来做屏蔽。

任意语言编写出来而定程序,最终都会转换为机器指令,按照一定的顺序去执行,所以在语言层面来讲,都是基于硬件层面提供的一致性模型的基础上,来实现自身语言的功能和特性。

经过前面对CPU的分析:

  • Java利用汇编的CAS + lock前缀指令来实现原子性。(synchronized,ReentrantLock)
  • Java利用lock前缀指令 + MESI协议来实现的可见性。(volatile)
  • Java基于内存屏障转换为lock前缀指令来实现有序性。(volatile)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/692997.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(三)Spring 核心之面向切面编程(AOP)—— 代理的创建

目录 一. 前言 二. 代理的创建 2.1. 创建前准备 2.2. 获取所有的 Advisor 2.3. 创建代理的入口方法 2.4. 依据条件创建代理(JDK 或 CGLIB) 三. 动态代理要解决什么问题 3.1. 什么是代理 3.2. 什么是动态代理 四. 总结 一. 前言 前面两篇文章《…

MyBatis学习总结

MyBatis分页如何实现 分页分为 逻辑分页:查询出所有的数据缓存到内存里面,在从内存中筛选出需要的数据进行分页 物理分页:直接用数据库语法进行分页limit mybatis提供四种方法分页: 直接在sql语句中分页,传递分页参数…

网贷大数据查询多了对征信有影响吗?

网贷大数据在日常的金融借贷中起到很重要的风控作用,不少银行已经将大数据检测作为重要的风控环节。很多人在申贷之前都会提前了解自己的大数据信用情况,那网贷大数据查询多了对征信有影响吗?本文带你一起去看看。 首先要说结论:那就是查询网…

[极客大挑战2019]upload

该题考点&#xff1a;后缀黑名单文件内容过滤php木马的几种书写方法 phtml可以解析php代码&#xff1b;<script language"php">eval($_POST[cmd]);</script> 犯蠢的点儿&#xff1a;利用html、php空格和php.不解析<script language"php"&…

软件测试工程师经典面试题

软件测试工程师&#xff0c;和开发工程师相比起来&#xff0c;虽然前期可能不会太深&#xff0c;但是涉及的面还是比较广的。前期面试实习生或者一年左右的岗位&#xff0c;问的也主要是一些基础性的问题比较多。涉及的知识主要有MySQL数据库的使用、Linux操作系统的使用、软件…

缓存驱动联邦学习架构赋能个性化边缘智能 | TMC 2024

缓存驱动联邦学习架构赋能个性化边缘智能 | TMC 2024 伴随着移动设备的普及与终端数据的爆炸式增长&#xff0c;边缘智能&#xff08;Edge Intelligence, EI&#xff09;逐渐成为研究领域的前沿。在这一浪潮中&#xff0c;联邦学习&#xff08;Federated Learning, FL&#xf…

leetcode hot100零钱兑换Ⅱ

本题可以看出也是背包问题&#xff0c;但区别于之前的01背包问题&#xff0c;这个是完全背包问题的变形形式。 下面介绍01背包和完全背包的区别与联系&#xff1a; 01背包是背包中的物品只能用一次&#xff0c;不可以重复使用&#xff0c;而完全背包则是可以重复使用。01/完全…

一个基于C#开发的、开源的特殊字符输入法

emoji表情在社交网络非常流行&#xff0c;我们在手机也非常方便输入&#xff0c;但是在PC电脑我们一般需要到归集好的网页拷贝&#xff0c;所以今天推荐一个Windows小工具&#xff0c;让你方便输入特殊字符和emoji表情。 01 项目简介 这是一个基于C#开发的开源项目&#xff0…

ansible及其模块

一、ansible是什么&#xff1f; Ansible是一个基于Python开发的配置管理和应用部署工具&#xff0c;现在也在自动化管理领域大放异彩。它融合了众多老牌运维工具的优点&#xff0c;Pubbet和Saltstack能实现的功能&#xff0c;Ansible基本上都可以实现。 Ansible能批量配置、部…

手动实现new操作符

<script>//前置知识// 每一个函数在创建之初就会有一个prototype属性&#xff0c;这个属性指向函数的原型对象// function abc(){// }// abc.prototype--> {constructor: f}// 在JS中任意的对象都有内置的属性叫做[[prototype]]这是一个私有属性&#xff0c;这个私有属…

如何用GPT进行论文写作?

一&#xff1a;AI领域最新技术 1.OpenAI新模型-GPT-5 2.谷歌新模型-Gemini Ultra 3.Meta新模型-LLama3 4.科大讯飞-星火认知 5.百度-文心一言 6.MoonshotAI-Kimi 7.智谱AI-GLM-4 二&#xff1a;GPT最新技术 1.最新大模型GPT-4 Turbo 2.最新发布的高级数据分析&#x…

安宝特AR汽车行业解决方案系列1-远程培训

在汽车行业中&#xff0c;AR技术的应用正悄然改变着整个产业链的运作方式&#xff0c;应用涵盖培训、汽修、汽车售后、PDI交付、质检以及汽车装配等&#xff0c;AR技术为多个环节都带来了前所未有的便利与效率提升。 安宝特AR将以系列推文的形式为读者逐一介绍在汽车行业中安宝…

使用 npm/yarn 等命令的时候会,为什么会发生 Error: certificate has expired

缘起 昨天&#xff0c;我写了一篇文章&#xff0c;介绍如何使用项目模板&#xff0c;构建一个 Electron 项目的脚手架&#xff0c;我发现我自己在本地无法运行成功&#xff0c;出现了错误。 ✖ Failed to install modules: ["electron-forge/plugin-vite^7.2.0",&qu…

多维时序 | Matlab实现BiLSTM-MATT双向长短期记忆神经网络融合多头注意力多变量时间序列预测模型

多维时序 | Matlab实现BiLSTM-MATT双向长短期记忆神经网络融合多头注意力多变量时间序列预测模型 目录 多维时序 | Matlab实现BiLSTM-MATT双向长短期记忆神经网络融合多头注意力多变量时间序列预测模型预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.多维时序 | Matlab…

第六十四天 服务攻防-框架安全CVE复现Apache shiroApache Solr

第六十四天 服务攻防-框架安全&CVE复现Apache shiro&Apache Solr 知识点: 中间件及框架列表: IIS,Apache,Nginx,Tomcat,Docker,K8s,Weblogic.JBoos,WebSphere, Jenkins,GlassFish,Jetty,Jira,Struts2,Laravel,Solr,Shiro,Thinkphp,Spring, Flask,jQuery等 1、开发框…

【DDD】学习笔记-薪资管理系统的场景驱动设计

场景驱动设计的起点是领域场景&#xff0c;它不一定需要与事件风暴结合&#xff0c;只要识别并确定了领域场景&#xff0c;就可以进行任务分解。每个分解出来的子任务都可以视为是职责。分配职责时&#xff0c;场景驱动设计规定了履行职责的角色构造型&#xff0c;其中&#xf…

嵌入式学习 Day 22

一. 时间获取: 1.time time_t time(time_t *tloc); 功能: 返回1970-1-1到现在的秒数&#xff08;格林威治时间&#xff09; 参数: tloc:存放秒数空间首地址 返回值: 成功返回秒数 失败返回-1 注意&#xff1a;两种方式都可…

144. Binary Tree Preorder Traversal(二叉树的前序遍历)

问题描述 给你二叉树的根节点 root &#xff0c;返回它节点值的 前序 遍历。 问题分析 因为要以数组的形式返回前序遍历序列所以与普通的前序遍历多了一步将返回的数组合并的过程&#xff0c;将当前二叉树的左子树&#xff0c;根&#xff0c;右子树按照顺序合并成为一个数组…

【漏洞复现】大华DSS视频管理系统信息泄露漏洞

Nx01 产品简介 大华DSS数字监控系统是一个在通用安防视频监控系统基础上设计开发的系统&#xff0c;除了具有普通安防视频监控系统的实时监视、云台操作、录像回放、报警处理、设备治理等功能外&#xff0c;更注重用户使用的便利性。 Nx02 漏洞描述 大华DSS视频管理系统存在信…

人工智能_CPU安装运行ChatGLM大模型_安装清华开源人工智能AI大模型ChatGlm-6B_004---人工智能工作笔记0099

上一节003节我们安装到最后,本来大模型都可以回答问题了,结果, 5分钟后给出提示,需要GPU,我去..继续看官网,如何配置CPU运行 没办法继续看: https://github.com/THUDM/ChatGLM-6B 这里是官网可以看到 需要gcc的版本是11.3.0,这里我们先没有去安装,直接试试再说 yum instal…