java硬件编程_关于JAVA并发编程你需要知道的——硬件篇

无论程序语言如何千变万化,他们都深深地根植于目前的计算机体系结构。

左图是intel CPU的三级高速缓存设计,由于高速缓存对程序员基本不可见,因此可以抽象为右图。

9531d4dcc475a128db952d181f7c3cd4.png

缓存的设计

首先还是先谈谈左图。

L1-cache分为两部分,i-cache存储指令(只读),d-cache存储数据(可读可写)

CPU只能和寄存器以及L1-cache进行直接交互,数据不能隔层传递,只能一层一层往上读,一层一层往下写

访问L1需要至少4个时钟周期,L2需要至少10个,L3需要至少30个。即便是速度最快的L1,也低于运算单元的执行速度,何况存在缓存未命中的情况,因此在L1和运算单元之间加上了Writebuffer和Readbuffer(合称Memory Ordering Buffer,MOB),数据准备好的时候再完成相关指令,这就是CPU指令乱序——顺序执行乱序完成。乱序完成的结果放入到Writebuffer中,按照原有的执行顺序,刷到缓存中

缓存由多个缓存行组成。每个缓存行结构如图所示(以64位机器为例)

4df52fc7218fcd15d484462c5458d40c.png

CPU读取缓存的时候找到对应的缓存行,如果前面的有效位为零,就从下一级缓存加载到这一级缓存

相关的问题

明白缓存的设计之后,再看右图来分析其中的问题

缓存导致的内存可见性:已知线程A运行在core 0上,线程B运行在core 1上,两者都对同一个内存地址进行读取,这个内存地址的内容会被加载到cache,然后CPU读取,这时候线程A对内容进行了修改,但是线程B却可能一直从本核心的cache读取,无法感知到该地址的内容已被修改。

多核导致的自增操作原子性:自增操作分为三步:从内存读取变量到寄存器;寄存器中的值加1;写回到内存。已知线程A运行在core 0上,线程B运行在core 1上,两者都对变量执行加一操作。A执行完一二两步时,B执行完第一步,A将加一后的值写入到内存,B执行完二三两步也将加一后的值写入到内存,结果变量只加了一,而不是加二

MOB导致的cache可见性:a=1.0; a=a/2; a=a-1.0;按照正常的逻辑,a最后的结果为-0.5;但是因为除法的执行时钟周期大于减法,第三句执行时,a/2的结果存放在writebuffer中还没写入到缓存,a-1.0中a的值已经从缓存中加载到readbuffer,也就是a-1.0=1.0-1.0=0 (高级语言不会出现这个问题,因为编译器已经做了处理,前面的伪代码仅表示逻辑)

相关的实现

为了解决这些问题,CPU提供了一些指令,其中比如lock和cmpxchg。

lock 汇编前缀,在Intel奔腾系列之前,这个指令前缀能够锁定总线,禁止其他CPU核心操作内存,执行完后边的指令后释放总线,在这个过程中其他CPU核心会监听总线,发现某个内存地址内容被修改,就会将本核心下的对应cache行有效位置0。因为锁总线会禁止所有内存操作,降低效率,因此在奔腾之后,这个指令前缀不锁总线而是锁定相关的cache行,对某个地址修改后直接让相关cache失效。这样解决了问题一

cmpxchg 将寄存器a中的值与内存中比较如果一样,将寄存器c中的值和内存中的值交换,如果不一样就设置异常位并将内存中的值读取到寄存器a。代入到问题二,从内存读取值到寄存器a,加一后保存到寄存器c,然后执行cmpxchg,执行完后如果有异常,就重新加一,再尝试写回,直到成功。这样解决了问题二

cmpxchg和lock 在执行完以后会将writebuffer刷到cache并清空readbuffer,这样解决了问题三。另外X86_64引入了内存屏障指令 lfence、sfence、mfence。lfence前面的读取操作完成,也就是readbuffer中的内容全部被cpu读取后,才能执行lfence之后的读取操作;sfence前面的写入操作完成,也就是writebuffer全部刷到缓存中,才能执行sfence之后的写入操作;mfence之前的读写操作全部完成,才能进行mfence之后的操作。

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

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

相关文章

net Core做一个webApi的简单实例

用NetCore 和Dapper 和mySql做一个简单的实例, 一准备工作 1:VS2017windos系统,也可以用其他的操作系统和工具 2:一台Cenetos的虚拟机或者虚拟机 二:开始 1:用微软官方的netCore的ToDo项目改造,…

java 文件输出流_Java 文件输出流

Java IO教程 - Java文件输出流创建输出流要写入文件,我们需要创建一个FileOutputStream类的对象,它将表示输出流。// Create a file output streamString destFile "test.txt";FileOutputStream fos new FileOutputStream(destFile);当写入文…

MySQL5.7参数log_timestamps

最近测试MySQL 5.7.21 Community Server这个版本的MySQL数据库时,发现其错误日志的时间跟系统当前时间不一致,后面检查发现日期时间格式都是UTC时间,查了一下相关资料,原来在MySQL 5.7.2 之后日志文件里面的时间戳从默认的本地系…

Tidb集群加mysql_TiDB - 快速入门,集群搭建

TiDB 是开源分布式关系型数据库,是一款同时支持在线事务处理与在线分析处理 (Hybrid Transactional and Analytical Processing, HTAP)的融合型分布式数据库产品,具备水平扩容或者缩容、金融级高可用、实时 HTAP、云原生的分布式数据库、兼容 MySQL 5.7 …

python递归函数

递归函数简单来说就是函数的自我调用。使用递归函数很多时候可以使得代码简洁,优雅。可以把复杂的问题分解成简单的子问题。递归有无与伦比的魅力,从著名的计算机名言就可以看出递归的奇妙: To iterate is human,to recurse divine. 迭代者为…

java知识体系 servlet_03-Servlet 体系结构知识梳理

一、Servlet体系结构Java Web应用是基于Servlet规范运行,Servlet顶层类的关联如下图:从图可看出,Servlet规范基本围绕这几个类运行,其中,与Servlet主动关联的有3个类,分别是ServletRequest、ServletRespons…

testlink自带java api_java如何连接testlink

1.下载相关的jar包2.获取到testlink的url和key,注意:url不是testlink的连接地址,是连接地址/lib/api/xmlrpc.php3.测试是否连接成功public static void main(String args[]) {String url "http://test.tl.gmsd.lan/lib/api/xmlrpc.php&…

lr背景虚化_lr背景虚化_怎样拍出背景模糊的照片

除了锐化之外,要获得独特的,令人难忘的图像,还可以使用其他方法,例如,相反的效果-单个细节的模糊。这样的方法将使人们有可能专注于整个构图的中心人物,为图片增加情感色彩,动作,并为…

在线五子棋JAVA网络编程_实验五 Java网络编程及安全

一、实验内容1.掌握Socket程序的编写;2.掌握密码技术的使用;3.设计安全传输系统。二、实验步骤1. 基于Java Socket实现安全传输2. 基于TCP实现客户端和服务器,结对编程一人负责客户端,一人负责服…

rnn中文语音识别java_语音识别算法阅读之RNN-T-2018

论文:EXPLORING ARCHITECTURES, DATA AND UNITS FOR STREAMING END-TO-END SPEECH RECOGNITION WITH RNN-TRANSDUCER,2018CTC的一个问题在于,其假设当前帧的输出与历史输出之间的条件独立性;RNN-T引入预测网络来弥补CTC这种条件独立性假设带来…

Storm环境搭建(分布式集群)

作为流计算的开篇,笔者首先给出storm的安装和部署,storm的第二篇,笔者将详细的介绍storm的工作原理。下边直接上干货,跟笔者的步伐一块儿安装storm。 原文链接:Storm环境搭建(分布式集群) Step1…

18.QT-QPlainEdit 信号与槽

QPlainEdit编辑功能 Public Slots void appendHtml ( const QString & html ) void appendPlainText ( const QString & text ) void centerCursor () void clear () void copy () void cut () void insertPlainText ( const QString & text ) void paste () void …

嘻嘻

今天我们来聊一下如何减肥? 其实我也不知道,嘻嘻~ 开个玩笑 好了,今天我们继续来学习新的知识。 在前两篇文章中,我们接触到了索引的概念,今天我们要对索引进行一个拓展。首先我们先来看一下下面这段代码: …

mysql :完整性约束

---恢复内容开始--- 一:介绍 约束条件与数据类型的宽度一样 ,都是可选参数 作用,用于保证数据的完整性和 一致性 主要分为: primary key (pk) 标识该字段为该表的主键, 可以唯一的标识记录 foreign key (fk…

php htts cookies,Http和Https下的cookie的写入问题

session和cookie是不一样的session存储在服务器,cookie存储在客户端设置cookie:function setcookie ($name, $value null, $expire null, $path null, $domain null, $secure null, $httponly null) {}获取cookie:$_COOKIE[$sCookieName];题主的写法只是操作了服务器端的…

java 做项目踩坑,web项目踩坑过程

sql函数设计:一开始本来是直接用Java的jdbc直接传输操作语句的。但后来学了存储过程发现存储过程可以提高不少的效率。就重构了自己对数据库的操作代码。包括:开启,查找,修改,关闭。开启:直接使用的构造函数…

matlab设计理想数字带通滤波器,基于matlab的数字带通滤波器课程设计报告

基于matlab的数字带通滤波器课程设计报告 1 西安文理学院机械电子工程系 课程设计报告 专业班级 08级电子信息工程1班 题 目 基于 MATLAB 的数字带通滤波器 学 号 学生姓名 指导教师 2011 年 12 月 西安文理学院机械电子工程系2 课程设计任务书 学生姓名 _______专业班级 _____…

xml序列号错误

xml序列号错误((XmlHelper.Deserialize))提示&#xff1a;XML 文档(1, 2)中有错误。{"不应有 <entryOrder xmlns>。"} 原因&#xff1a;1.缺少根目录&#xff08;<root>&#xff09;2.xml字段转换失败&#xff08;string->int&#xff09; ----------…

关于windows10 CMD 的一些操作

之前接触过cmd的一些操作方法&#xff0c;比如用dir、tasklist等一些方法&#xff0c;但是用了会立马忘记&#xff0c;再用到时又要重新google&#xff0c;这着实让我头痛&#xff01;&#xff01;&#xff01; 今天又碰到一个关于改变目录的问题&#xff0c;又是纠结万分&…

oracle dblink 验证,Oracle DBLINK 简单使用

oracle在进行跨库访问时&#xff0c;可以通过创建dblink实现&#xff0c;今天就简单的介绍下如果创建dblink&#xff0c;以及通过dblink完成插入、修改、删除等操作首先了解下环境&#xff1a;在tnsnames.ora中配置两个数据库别名&#xff1a;orcl(用户名&#xff1a;wangyong …