java 多线程写缓存,Java多线程_缓存对齐

1.什么是缓存对齐

当前的电脑中,数据存储在磁盘上,可以断电保存,但是读取效率较低。不断电的情况下,数据可以在内存中存储,相对硬盘效率差不多是磁盘的一万倍左右。但是运算时,速度最快的是直接缓存在CPU中的数据。CPU有三级缓存分别是L1,L2,L3三级,CPU访问速度大概是内存的100倍。

1.1CPU结构

对于一台电脑,其主板可以支持多少个CPU插槽,称为CPU个数。对于一颗多核CPU,单片CPU上集成的处理核心称为CPU核数。对于每个核心,可以给每个核设置两组寄存器,两组pc。

a81b1ba4c3fef157bc2c7b72417ddb5d.png

CPU结构如上图所示(图片来自网络),对于一块CPU,可以有多个处理核心。每个核心内有自己的L1,L2缓存,多个核心共用同一个L3缓存。但一个电脑如果有多个CPU插槽,各个CPU有自己的L3。对于一个CPU核心来说,每个核心都有ALU,逻辑运算单元。负责对指令进行计算。Register 寄存器,记录线程执行对应的数据。PC:指令寄存器,记录线程执行到了哪个位置。里面存的是指令行数。通俗讲,就是记录线程执行到了哪一行指令(代码在进入CPU运行前,会被编译成指令)了。

线程在执行的时候,将当前线程对应的数据放入寄存器,将执行行数放到指令寄存器,然后执行过一个时间片后,如果线程没有执行完,将数据和指令保存,然后其他线程进入执行。一个ALU对应多个PC|registers的时候(所谓的四核八线程)。一般来说,同一个CPU核在同一个时间点,只能执行同一个线程,但是,如果一个核里面有两组寄存器,两个pc。那么就可以同时执行两组线程,在切换线程的时候,没必要再去等待寄存器的数据保存和数据载入。直接切换到下一组寄存器就可以。这就是超线程。

1.2缓存对齐

fc889cc0d00f8190f3d3059a2bc1b9ea.png

CPU到内存之间有很多层的内存,如图所示,CPU需要经过L1,L2,L3及主内存才能读到数据。从主内存读取数据时的过程如下:

当我左侧的CPU读取x的值的时候,首先会去L1缓存中去找x的值,如果没有,那么取L2,L3依次去找。最后从主内存读入的时候,首先将内存数据读入L3,然后L2最后L1,然后再进行运算。但是读取的时候,并不是只读一个X的值,而是按块去读取(跟电脑的总线宽度有关,一次读取一块的数据,效率更高)。CPU读取X后,很可能会用到相邻的数据,所以在读X的时候,会把同一块中的Y数据也读进来。这样在用Y的时候,直接从L1中取数据就可以了。

读取的块就叫做缓存行,cache line 。缓存行越大,局部性空间效率越高,但读取时间慢。缓存行越小,局部性空间效率越低,但读取时间快。目前多取一个平衡的值,64字节。

然后,如果你的X和y在同一块缓存行中,且两个字段都用volatile修饰了,那么将来两个线程再修改的时候,就需要将x和y发生修改的消息高速另外一个线程,让它重新加载对应缓存,然而另外一个线程并没有使用该缓存行中对应的内容,只是因为缓存行读取的时候跟变量相邻,这就会产生效率问题。

解决起来也简单,我们将数据中的两个volatile之间插入一些无用的内存,将第二个值挤出当前缓存行,那么执行的时候,就不会出现相应问题了。提高代码效率。

2.缓存对齐在java中实现

在java中,jdk一些涉及到多线程的类,有时候会看到类似于public volatile long p1,p2,p3,p4,p5,p6,p7;这样的代码,有的就是做的缓存行对齐。

我们设计一个实验去验证缓存行对齐的导致的性能问题,及相关的解决后的效率问题。具体代码见第三小节。这里的思路是,首先,我们写一个类T,这个类里面有一个用volatile修饰的long属性的值,这个值占用8个字节。然后声明一个静态数组,包含两个元素,分别T的两个对象。然后开启两个线程,让两个线程分别给数组的第一个值和第二个值赋值,执行一百万次,看执行的耗时。

这个时候,代码执行的时候如1.2的图中所示,假设数组中第一个值为X,第二个值为Y。左侧框内为第一个线程,执行修改X值的操作,右侧框内为第二个线程,修改Y的值。因为两个值在同一个缓存行中,所以在X值在读取的时候,同时将X值和Y值一起读入缓存。第二个线程只修改Y的值,但是同样将XY全部读入缓存。线程1中X值发生修改后,第二个线程中的X值需要进行更新。而线程2修改Y的值后也需要同样的操作,但是这个更新不是必要的,而且会影响执行的效率。

解决方法是:我们给第T的long值之前加入8个long值,这样Y值就会被挤到其他缓存行,这样彼此修改的时候就不会产生干扰,提高代码执行效率。

下面是具体验证的代码,其中在没有加入父类的时候,是相互干扰时的执行耗时。第二个是加入父类后,不再干扰时的耗时,执行后可以看出,第二套代码在执行的时候,代码要优于第一套代码的执行。

3.缓存对齐的代码实现

1 public classT01_CacheLinePadding {2 private static classT{3 public long x = 0L;4 }5 public static T[] orr = new T[2];6 static{7 orr[0]= newT();8 orr[1]= newT();9 }10 public static void main(String[] args) throwsException {11 Thread t1 = new Thread(()->{12 for (long i = 0; i < 1000_000L; i++) {13 orr[0].x =i;14 }15 });16 Thread t2 = new Thread(()->{17 for (long i = 0; i < 1000_000L; i++) {18 orr[1].x =i;19 }20 });21 final long start =System.nanoTime();22 t1.start();23 t2.start();24 t1.join();25 t2.join();26 System.out.println((System.nanoTime()-start)/100_000);27 }28 }

1 packagemsb;2 /**

3 * 缓存行对齐问题代码4 *@authorL Ys5 *6 */

7 public classT02_CacheLinePadding {8 private static classPadding{9 public longp1,p2,p3,p4,p5,p6,p7;10 }11 private static class T extendsPadding{12 public volatile long x = 0L;13 }14 public static T[] orr = new T[2];15 static{16 orr[0]= newT();17 orr[1]= newT();18 }19 public static void main(String[] args) throwsException {20 Thread t1 = new Thread(()->{21 for (long i = 0; i < 1000_000L; i++) {22 orr[0].x =i;23 }24 });25 Thread t2 = new Thread(()->{26 for (long i = 0; i < 1000_000L; i++) {27 orr[1].x =i;28 }29 });30 final long start =System.nanoTime();31 t1.start();32 t2.start();33 t1.join();34 t2.join();35 System.out.println((System.nanoTime()-start)/100_000);36 }37 }

程序员灯塔

转载请注明原文链接:Java多线程_缓存对齐

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

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

相关文章

ArcGIS Server SOE开发之奇怪异常:

添加之后结果显示如下:fjsontokenezkBvir0Tj5q31UEst7pTFPwrwocmHklCajKeh-xXM91qWdBXDuQMmtGcaHaaXCJ 具体如下: 该SOE扩展在另一台机器上测试时可以正常添加,不知道为什么,在此台机器上添加时就出现如下异常. 请教群里大神,大神建议换个浏览器试试,换成IE在添加扩展,竟然成功…

netbeans7.4_NetBeans 7.2引入了TestNG

netbeans7.4代码生成的优点之一是能够查看如何使用特定的语言功能或框架。 正如我在《 NetBeans 7.2 beta&#xff1a;更快&#xff0c;更有用》一文中所讨论的那样&#xff0c; NetBeans 7.2 beta提供了TestNG集成 。 除了对该功能的单一引用之外&#xff0c;我在该帖子中没有…

2016年成功的Java开发人员简介

2015年即将结束。 现在是时候总结过去一年做了什么和没有做什么的时候了。 此外&#xff0c;现在是预测下一个2016年的好时机。 您已经猜到这篇文章是关于2016年理想的Java开发人员的。 我想给你一个惊喜&#xff0c;这次我更改了预测的格​​式。 为了使预测更非个人化&#…

使用Java 8 Lambda,流和聚合

总览 在本文中&#xff0c;我们将介绍使用Java 8 lambda&#xff0c;流和聚合来过滤和操作Collection中的对象。 这篇文章中的所有代码都可以在BitBucket中找到 。 在此示例中&#xff0c;我们将创建许多对象&#xff0c;这些对象代表我们IT基础架构中的服务器。 我们将这些对…

易语言微凉模块oracle,跟着微凉学易语言 【简单子类化】

本帖最后由 【微凉清风】 于 2011-1-20 18:23 编辑易语言的子类化文章太少了,本人文笔也不好哈,看看VB得吧,别说英文看不懂,看不懂你的易语言水平永远不会提高!一,初识子类当你还不碰过子类的时候,你看到这个标题,定会问:"啥叫子类?".因为你知道我定会为你解答.(阴险…

node服务的监控预警系统架构

需求背景 目前node端的服务逐渐成熟&#xff0c;在不少公司内部也开始承担业务处理或者视图渲染工作。不同于个人开发的简单服务器&#xff0c;企业级的node服务要求更为苛刻&#xff1a; 高稳定性、高可靠性、鲁棒性以及直观的监控和报警 想象下一个存在安全隐患且没有监控预警…

jaxb util_JAXB自定义绑定– Java.util.Date / Spring 3序列化

jaxb utilJaxB可以处理Java.util.Date序列化&#xff0c;但是需要以下格式&#xff1a; “ yyyy-MM-ddTHH&#xff1a;mm&#xff1a;ss ”。 如果需要将日期对象格式化为另一种格式怎么办&#xff1f; 我有同样的问题时&#xff0c;我正在同春MVC 3和Jackson JSON处理器 &…

oracle数据库没有选项,创建oracle数据库时,出现ORA-00922: 选项缺失或无效

sdd53HOME新建oracle数据库时遇到ORA-00922: 选项缺失或无效的问题&#xff0c;如图&#xff1a;原因&#xff1a;一般是语句的语法有问题。比如命名不对&#xff0c;关键字写错等等。对于非标准的命名&#xff0c;一般采用双引号来创建。具体原因&#xff1a;就是开始的用户密…

oracle 导出 cuow,直通伍伦贡大学的升学保障— 伍伦贡大学学院(UOWC)

伍伦贡大学学院是直属大学的桥梁课程提供者&#xff0c;为没有达到直入本科的学生提供另一种进入大学的途径&#xff0c;也为大学提供语言类课程。自1989年成立以来&#xff0c;为大学输送了数以千计的优秀学生。目前学院有来自世界30多个国家超过2000名在校生。在伍伦贡大学学…

async 和 await 的进阶

异常的捕获&#xff1a; static void Main(string[] args){//继续我们的异步编程的使用嘀呀&#xff1b;//关于主线程是无法捕获我们子线程中的异常滴滴啊&#xff1b;var t DoExceptionAsync();t.Wait();Console.WriteLine($"{nameof(t.Status)}: {t.Status}"); …

Spark Shell的简单使用

简介 Spark shell是一个特别适合快速开发Spark原型程序的工具&#xff0c;可以帮助我们熟悉Scala语言。即使你对Scala不熟悉&#xff0c;仍然可以使用这个工具。Spark shell使得用户可以和Spark集群交互&#xff0c;提交查询&#xff0c;这便于调试&#xff0c;也便于初学者使用…

w10系统自带linux系统,win10下,内置linux系统的安装和体验,你造吗?

原标题&#xff1a;win10下&#xff0c;内置linux系统的安装和体验&#xff0c;你造吗&#xff1f;众所周知&#xff0c;windows系统和linux系统一直是水火不容&#xff0c;而在最新的win10系统却完美兼容了linux系统&#xff0c;但是在默认情况下是关闭的&#xff0c;需要我们…

北风网09.接收普通消息2

该公众号暂时无法提供服务,请稍后再试 转载于:https://www.cnblogs.com/ZHONGZHENHUA/p/6273960.html

中科软测试面试题2019_2019国考成绩今日是否会发布,笔试120能进面不?

2019国考成绩要出来了不&#xff1f;2019国考成绩何时出来&#xff1f;现在已是1月中旬&#xff0c;许多考生对于自己的国考笔试成绩都非常期待&#xff0c;而最近风声四起&#xff0c;搞得考生们人心慌慌&#xff0c;那么2019国考成绩要出来了不&#xff1f;现在我们一起来分析…

C# 数据库连接测试以及备份

现在我们要做一个如图5.1的数据库连接配置&#xff0c;从界面上看有三个功能需要实现&#xff1a;从配置文件中读取数据库连接的相关属性、备份数据库、测试连接。 现在我们就一个一个开始讲解。 图5.1 1.从配置文件中读取数据库连接的相关属性 1) 配置文件中的数据库连接: &l…

Linux程序选择boy糊者girl,linux脚本程序练习-Go语言中文社区

1、编写一个名为iffile程序&#xff0c;它执行时判断/bin目录下date文件是否存在&#xff1f;2、编写一个名为greet的问候程序&#xff0c;执行时能根据系统当前的时间向用户输出问候信息。设从半夜到中午为早晨&#xff0c;中午到下午六点为下午&#xff0c;下午六点到半夜为晚…

什么是初效过滤器_初效过滤器怎么样 初效过滤器特点介绍【详解】

说起过滤器&#xff0c;我们大家都不陌生。现在环境污染严重&#xff0c;我们大多数家庭都在使用 净水器 、 空气净化器 等家电设备&#xff0c;它们需要依靠过滤器来净化水质和空气&#xff0c;让我们的生活更加健康。不过&#xff0c;您知道初效过滤器安装的步骤是什么吗?下…

云计算hcie贴吧_专业介绍|计算机网络技术

点击蓝字关注我们01专业特色计算机网络技术专业所有在职专任教师都具有高级职称和硕士学位&#xff0c;双师比例为75&#xff05;&#xff1b;在企业核心岗位工作的兼职老师4人。筹备组建华为ICT学院。华为ICT学院是华为公司主导的&#xff0c;面向全球在校大学生传递华为ICT技…

linux日志自动按天保存,linux实现按天生成日志文件并自动清理

linux实现按天生成日志文件并自动清理前篇文章中讲到如何在Linux crontab创建每秒执行的方法&#xff0c;高人可能早意识到日志文件没做处理&#xff0c;假如没人工处理久了日后越来越大肯定会出现问题&#xff0c;当然人工处理也不现实。为了解决这个问题&#xff0c;所以有了…

通达信版弘历软件指标_中线公式指标(副图 通达信 贴图)明确文字提示,辅助判断中线走势下载_通达信公式...

中线公式指标(副图 通达信 贴图)明确文字提示&#xff0c;辅助判断中线走势下载详细说明第一股票公式网()告诉您&#xff1a;当前正要下载&#xff1a;中线公式指标(副图 通达信 贴图)明确文字提示&#xff0c;辅助判断中线走势下载 中线公式指标(副图 通达信 贴图)明确文字提示…