当前位置: 首页 > news >正文

volatile 关键字 与 CPU cache line 的效率问题

分析&回答

Cache Line可以简单的理解为CPU Cache中的最小缓存单位。目前主流的CPU Cache的Cache Line大小都是64Bytes。假设我们有一个512字节的一级缓存,那么按照64B的缓存单位大小来算,这个一级缓存所能存放的缓存个数就是512/64 = 8个。具体参见下图:

代码示例:

public class CacheLine {private static class T {public volatile long x = 0L;//long类型占据8个字节}public static T[]  arr = new T[2];static {arr[0] = new T();arr[1] = new T();//两个数组紧挨着保证在内存中也是挨在一起的}public static void main(String[] args) throws Exception{Thread t1 = new Thread(() -> {for (long i = 0; i<10000000L; i++) {arr[0].x = i;//修改一千万次}});Thread t2 = new Thread(() -> {for (long i = 0; i<10000000L; i++) {arr[1].x = i;//修改一千万次}});final long start = System.currentTimeMillis();t1.start();t2.start();t1.join();//让t1线程先执行完t2.join();//让t2线程执行完System.out.println(System.currentTimeMillis() - start);//join 保证主线程的这段代码最后执行}
}
复制代码

执行结果为 300ms左右
上面代码中 arr[0] 和 arr[1]会在同一个cache line中,而每个cache line 是cpu 读入的最基本单位,在我们使用vaolatile 之后线程t1对x的1000000万次修改都要刷新内存通知t2,而同样t2对x的修改也要告诉t1。这样就会存在频繁的cache line 和内存的刷新读取。
如果我们将 对x的修饰的valitile去掉执行结果为10ms左右\

使用缓存行对其的方式代码示例:

public class CacheLine {private static class parent {public volatile long p1,p2,p3,p4,p5,p6,p7;//创建七个long 基本数据类型的成员变量占据56个字节}private static class T extends parent{public volatile  long x = 0L;//long类型占据8个字节}public static T[]  arr = new T[2];static {arr[0] = new T();arr[1] = new T();//两个数组紧挨着保证在内存中也是挨在一起的}public static void main(String[] args) throws Exception{Thread t1 = new Thread(() -> {for (long i = 0; i<10000000L; i++) {arr[0].x = i;//修改一千万次}});Thread t2 = new Thread(() -> {for (long i = 0; i<10000000L; i++) {arr[1].x = i;//修改一千万次}});final long start = System.currentTimeMillis();t1.start();t2.start();t1.join();//让t1线程先执行完t2.join();//让t2线程执行完System.out.println(System.currentTimeMillis() - start);//join 保证主线程的这段代码最后执行}
}
复制代码

执行结果为 100ms左右
现成t1一次读入x 包括p1p2p3p4p5p6p7的所有变量64个字节刚好占据一个缓存行,线程t2 也是如此,所以他们对变量x的修改都不用刷新内存通知对方提高了性能。
为什么这里不包括对象头的那部分呢,因为对相头不是使用的部分,不会读入缓存,我们用到的只是成员变量
总结为cpu对于内存的读入到缓存的数据是按照缓存行的大小(64k)来读取的。

反思&扩展

cache 是为了进一步提升计算机性能引入的存储结构,cache和内存的最小的传输单位是cache line,因为每个物理core有自己独享的L1、L2 cache,并且一个cache line可能存在多个cache中,所以就出现了MESI协议保证cache line的一致性。 进而又引入了cache line的伪共享的问题,为了进一步降低cache line伪共享所带来的的消耗,我们应该尽量避免多个线程同时修改的不同变量在同一个cache line中。虽然真实业务场景中,cache line的消耗占比可能会被弱化很多,但是追求极致的程序猿们,又怎么能放过这样一个无意义的消耗呢!

喵呜面试助手:一站式解决面试问题,你可以搜索微信小程序 [喵呜面试助手] 或关注 [喵呜刷题] -> 面试助手 免费刷题。如有好的面试知识或技巧期待您的共享!

相关文章:

volatile 关键字 与 CPU cache line 的效率问题

分析&回答 Cache Line可以简单的理解为CPU Cache中的最小缓存单位。目前主流的CPU Cache的Cache Line大小都是64Bytes。假设我们有一个512字节的一级缓存&#xff0c;那么按照64B的缓存单位大小来算&#xff0c;这个一级缓存所能存放的缓存个数就是512/64 8个。具体参见下…...

又一关键系统上线,理想车云和自动驾驶系统登陆OceanBase

8 月 1 日&#xff0c;理想汽车公布 7 月交付数据&#xff0c;理想汽车 2023 年 7 月共交付新车 34,134 辆&#xff0c;同比增长 227.5%&#xff0c;并已连续两个月交付量突破三万。至此&#xff0c;理想汽车 2023 年累计交付量已经达到 173,251 辆&#xff0c;远超 2022 年全年…...

SIEM(安全信息和事件管理)解决方案

什么是SIEM 安全信息和事件管理&#xff08;SIEM&#xff09;是一种可帮助组织在安全威胁危害到业务运营之前检测、分析和响应安全威胁的解决方案&#xff0c;将安全信息管理 (SIM) 和安全事件管理 (SEM) 结合到一个安全管理系统中。SIEM 技术从广泛来源收集事件日志数据&…...

Go 自学:map关联数组

以下代码展示了如何建立一个map。 我们可以使用delete删除map中的元素。 我们还可以使用loop遍历map中的所有元素。 package mainimport ("fmt" )func main() {languages : make(map[string]string)languages["JS"] "Javascript"languages[&qu…...

c#多态(override)的使用

方法重写&#xff08;override&#xff09;:多态&#xff0c;通过父类类型对象&#xff0c;调用子类当中对应方法的实现。 细节&#xff1a;子类当中的override方法会“抹杀”父类当中对应virtual方法 不使用多态时&#xff0c;父类调用子类方法时&#xff0c;会调用父类的方法…...

kafka 动态扩容现有 topic 的分区数和副本数

文章目录 [toc]创建一个演示 topic生产一些数据使用消费者组消费数据增加分区无新数据产生&#xff0c;有旧数据未消费有新数据产生&#xff0c;有旧数据未消费 增加副本创建 json 文件使用指定的 json 文件增加 topic 的副本数使用指定的 json 文件查看 topic 的副本数增加的进…...

【数据结构】Golang 实现单链表

概念 通过指针将一组零散的内存块串联在一起 &#xff0c; 把内存块称为链表的“结点”。 记录下个结点地址的指针叫作后继指针 next &#xff0c;第一个结点叫作头结点&#xff0c;把最后一个结点叫作尾结点 。 代码实现 定义单链表 在 golang 中可以通过结构体定义单链表…...

云服务器利用Docker搭建sqli-labs靶场环境

一、安装宝塔面板 使用xshell、electerm、SecureCRT等远程终端连接登陆上云服务器&#xff0c;在Linux宝塔面板使用脚本安装 安装后&#xff0c;如下图&#xff1a;按照提示&#xff0c;在云服务器防火墙/安全组放行Linux宝塔面板的端口 在浏览器打开上述网址&#xff0c;登…...

jQuery成功之路——jQuery介绍和jQuery选择器概述

一、jQuery介绍 1.1 jQuery概述 jQuery的概述 jQuery是一个快速、简洁的JavaScript框架。jQuery设计的宗旨是“write Less&#xff0c;Do More”&#xff0c;即倡导写更少的代码&#xff0c;做更多的事情。JQuery封装了JavaScript常用的功能代码&#xff0c;提供了一套易于使…...

极限五分钟,在宝塔中用 Docker 部署升讯威在线客服系统

最近客服系统成功经受住了客户现场组织的压力测试&#xff0c;获得了客户的认可。 客户组织多名客服上线后&#xff0c;所有员工同一时间打开访客页面疯狂不停的给在线客服发消息&#xff0c;系统稳定无异常无掉线&#xff0c;客服回复消息正常。消息实时到达无任何延迟。 本文…...

Java--静态字段与静态方法

1、静态字段 如果将一个字段定义为static&#xff0c;每个类只有一个这样的字段。而对于非静态的实例字段&#xff0c;每个对象都有自己的一个副本。 例如&#xff1a; class Employee {private static int nextId 1;private int id;... }其中&#xff0c;每一个Employee对…...

多线程的五种“打开”方式

1 概念 1.1 线程是什么&#xff1f;&#xff1f; 线程&#xff08;Thread&#xff09;是计算机科学中的一个基本概念&#xff0c;它是进程&#xff08;Process&#xff09;中的一个执行单元&#xff0c;负责执行程序的指令序列。线程是操作系统能够进行调度和执行的最小单位。…...

信息熵 条件熵 交叉熵 联合熵 相对熵(KL散度) 互信息(信息增益)

粗略版快速总结 条件熵 H ( Q ∣ P ) 联合熵 H ( P , Q ) − H ( P ) 条件熵H(Q∣P)联合熵H(P,Q)−H(P) 条件熵H(Q∣P)联合熵H(P,Q)−H(P) 信息增益 I ( P , Q ) H ( P ) − H ( P ∣ Q ) H ( P ) H ( Q ) − H ( P , Q ) 信息增益 I(P,Q)H(P)−H(P∣Q)H(P)H(Q)-H(P,Q) 信息…...

Fiddler Response私人订制

在客户端接口的测试中&#xff0c;我们经常会需要模拟各种返回状态或者特定的返回值&#xff0c;常见的是用Fiddler模拟各种请求返回值场景&#xff0c;如重定向AutoResponder、请求拦截修改再下发等等。小编在近期的测试中遇到的一些特殊的请求返回模拟的测试场景&#xff0c;…...

【德哥说库系列】-ASM管理Oracle 19C单实例部署

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&am…...

手写一个简单爬虫--手刃豆瓣top250排行榜

#拿到页面面源代码 request #通过re来提取想要的有效信息 re import requests import re url"https://movie.douban.com/top250"headers{"user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/11…...

【word密码】如何限制word文件中部分内容?

Word文件中有一部分内容不想他人编辑&#xff0c;我们可以设置限制编辑&#xff0c;可以对一部分内容设置限制编辑&#xff0c;具体方法如下&#xff1a; 我们将需要将可以编辑的地方选中&#xff0c;然后打开限制编辑功能 然后勾选限制编辑设置界面中的【限制编辑】和【每个人…...

spring 自定义类型转换-ConverterRegistry

1背景介绍 一个应用工程里面&#xff0c;一遍会涉及到很多的模型转换&#xff0c;如DTO模型转DO模型&#xff0c;DO模型转DTO, 或者Request转DTO模型&#xff0c;总的来说&#xff0c;维护起来还是相对比较复杂。每涉及一个转换都需要重新写对应类的get或者set方法&#xff0c…...

springboot实现发送短信验证码

目录 一、选择并注册短信服务提供商&#xff1a; 二、添加依赖&#xff1a; 三、配置短信服务信息&#xff1a; 四、编写发送短信验证码的方法&#xff1a; 五、调用发送短信验证码的方法&#xff1a; 一、选择并注册短信服务提供商&#xff1a; 1、选择一个可靠的短信服…...

2024王道408数据结构P144 T18

2024王道408数据结构P144 T18 思考过程 首先还是先看题目的意思&#xff0c;让我们在中序线索二叉树里查找指定结点在后序的前驱结点&#xff0c;这题有一点难至少对我来说…我讲的不清楚理解一下我做的也有点糊涂。在创建结构体时多两个变量ltag和rtag&#xff0c;当ltag0时…...

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界&#xff0c;看笔记好好学多敲多打&#xff0c;每个人都是大神&#xff01; 题目&#xff1a;KubeSphere 容器平台高可用&#xff1a;环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

微信小程序之bind和catch

这两个呢&#xff0c;都是绑定事件用的&#xff0c;具体使用有些小区别。 官方文档&#xff1a; 事件冒泡处理不同 bind&#xff1a;绑定的事件会向上冒泡&#xff0c;即触发当前组件的事件后&#xff0c;还会继续触发父组件的相同事件。例如&#xff0c;有一个子视图绑定了b…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)

CSI-2 协议详细解析 (一&#xff09; 1. CSI-2层定义&#xff08;CSI-2 Layer Definitions&#xff09; 分层结构 &#xff1a;CSI-2协议分为6层&#xff1a; 物理层&#xff08;PHY Layer&#xff09; &#xff1a; 定义电气特性、时钟机制和传输介质&#xff08;导线&#…...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式&#xff08;Python 实现&#xff09; 在 Python 中&#xff0c;你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是&#xff0c;.doc 是旧的 Word 格式&#xff0c;而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

汇编常见指令

汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX&#xff08;不访问内存&#xff09;XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南

精益数据分析&#xff08;97/126&#xff09;&#xff1a;邮件营销与用户参与度的关键指标优化指南 在数字化营销时代&#xff0c;邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天&#xff0c;我们将深入解析邮件打开率、网站可用性、页面参与时…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状&#xff1a;装配工作依赖人工经验&#xff0c;装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书&#xff0c;但在实际执行中&#xff0c;工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

python爬虫——气象数据爬取

一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用&#xff1a; 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests&#xff1a;发送 …...

土建施工员考试:建筑施工技术重点知识有哪些?

《管理实务》是土建施工员考试中侧重实操应用与管理能力的科目&#xff0c;核心考查施工组织、质量安全、进度成本等现场管理要点。以下是结合考试大纲与高频考点整理的重点内容&#xff0c;附学习方向和应试技巧&#xff1a; 一、施工组织与进度管理 核心目标&#xff1a; 规…...

怎么开发一个网络协议模块(C语言框架)之(六) ——通用对象池总结(核心)

+---------------------------+ | operEntryTbl[] | ← 操作对象池 (对象数组) +---------------------------+ | 0 | 1 | 2 | ... | N-1 | +---------------------------+↓ 初始化时全部加入 +------------------------+ +-------------------------+ | …...