Java-伪共享

在说这个计算机术语之前,我先在这里问候所有问“什么是JVM伪共享”的垃圾JAVA程序员以及一瓶不满半瓶晃荡的面试官全家

我从来没想过国内已经很卷的JAVA圈,已经卷到语无伦次的地步了,“伪共享”是java程序员应该知道的吗?能问出这个问题的人,除了炫技(不知道从哪个网站得知的概念),这就好比我问一个UI,photoshop是如何实现的一样,在我看来,他会觉得我很NB,但是在他的眼中,我和SB有什么区别

吐槽完毕,伪共享,指的是一种现象,如果出现了这种现象,那就叫做伪共享,我以mysql的一个表做示例,相信你很快明白,下面是一个很简单的数据库表
在这里插入图片描述

假设现在我开启2个事务
事务1:修改id=1这条数据的name
事务2:修改id=1这条数据的age

如果我们不知道锁的颗粒度为行锁的情况下,我们会以为:
虽然是同一行,但是字段不同,事务1和事务2完全不冲突,那么它们应该并发的进行修改

很明显,我们上述的想法(以为)是错误的,虽然name和age是不同的字段,但是它们是一行数据,由于锁的最小粒度是行级,所以,要么事务1执行完之后,再执行事务2,或者事务2执行之后再执行事务1,总之,它俩不会一起执行,总要有个先后

我们上述的想法中的现象,就是伪共享,也就是“事务1和事务2完全不冲突”这个现象,就是伪共享,说白了就是这句话是错误的,我们以为可以同时修改,但是他们不会同时修改,这种现象,就是伪共享

伪共享现象的存在,导致可以运行的更快的程序,无法运行的更快,下面的方式可以解决伪共享,对于本例来说
建立2个表,一个name表,专门存name,一个age表,专门存age,这样的话事务1和事务2相互之间没有冲突

文章到此为止,你应该知道什么叫做伪共享,以及如何解决伪共享,下面说一个新的概念:cacheline
CPU与内存之间速度有巨大差异,为了减少这个差异,在CPU和内存之间,会有多个叫cacheline的缓存,多核CPU,多个核共享cacheline

将上述的伪共享例子带入实际情况,如下:
1:上述示例中的【数据库表】,指的就是cacheline
2:上述示例中的【事务1】和【事务2】,指的是多核CPU的多个核
3:上述示例中的name和age指的是内存中的数据

假设CPU有2个核,分别是核1和核2,并且按照如下先后顺序执行,此处涉及到局部性原理,不过问题不大
1:核1读取name数据,先判断的cacheline中是否有name,发现没有,则去内存中读取name,因为我们定义变量的时候,name和age是挨着的,所以顺便也把age读出来了(局部性原理),然后将name和age放到cacheline X中
2:核2读取age数据,先判断cacheline中是否有age,发现cacheline X中存在age(核1顺手带过来的),此时则不会再去内存中读取
此时,核1修改cacheline X中的name,并且再修改的过程中,核2修改的cacheline X中的age,这个时候,伪共享现象出现,因为CPU为了保证数据一致,一个核修改一个cacheline的时候,其他核心是不允许修改这个cacheline的

解决伪共享:核1读取name的时候,不要顺手把age放到cacheline X中,但是考虑到局部性原理,读取是成块操作的,只有一个办法,那就是让name和age分开,读取name的时候,name附近的那块数据里没有age即可,这样的话核1读取name的时候,会把name缓存到cacheline X中,当核2读取age的时候,很大可能将age缓存到cachelien Y中,这样,name和age就不在一个cacheline中了,之后核1与核2可并发修改name和age

如何将name和age分开:非常简单,将name和age两个属性分开,中间使用其他属性,例如sex什么的即可,或者,name和age两个属性不必分开,但是要保持足够宽,为了保证足够宽,可将name后面用0填充,或者在age前面用0填充内存,确保它俩占用两个cacheline

Java使用的是0填充的方式,以空间换取速度,在java中,0填充使用的是long类型,不过无所谓,主要目的就是0填充

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

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

相关文章

kubernetes 网络解析

开头语 写在前面:如有问题,以你为准, 目前24年应届生,各位大佬轻喷,部分资料与图片来自网络 内容较长,页面右上角目录方便跳转 基础 Kubernetes 使用扁平网络模型,所有 Pod 都可以直接相互…

两种方式实现mysql截取年月日

select date_format(now(), %Y-%m-%d) select substring(now(), 1, 10)

大创项目推荐 深度学习实现行人重识别 - python opencv yolo Reid

文章目录 0 前言1 课题背景2 效果展示3 行人检测4 行人重识别5 其他工具6 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 **基于深度学习的行人重识别算法研究与实现 ** 该项目较为新颖,适合作为竞赛课题方向&#xff0c…

如何使用Jamf管理Apple文件保险箱

在当今的移动工作和教育环境中,Apple 设备的一个关键功能是内置的 macOS 加密技术,该技术保护组织数据和用户隐私。配备 Apple M1 芯片的最新计算机还具有额外的加密功能。 虽然这些安全层有助于保护最终用户手中的设备,无论他们在哪里工作或…

面向设计师的11个必备AI工具

在当今快速发展的设计领域,人工智能(AI)工具已成为不可或缺的创新催化剂。这些工具专门用于提高效率和创造力,从而重新定义传统的设计方法。AI正在彻底改变设计师的工作方式,从自动处理任务到发掘新的创造力机会&#…

Helix QAC 2023.4 新版支持C++20语言,带来更多性能提升!

Helix QAC 2023.4 新增功能 Helix QAC 2023.4全面支持MISRA C:2023规则,涵盖100%的指南。此版本还加强了对C20语言的支持,改进了数据流分析性能,并在整个产品中增加了多项用户体验改进。 增强的C20支持 此版本新增了对以下语言特性的支持&a…

Nginx配置jks格式证书,升级https

通常在给服务器升级https,需要在nginx上配置域名对应的https证书,nginx通常配置的是crt和key格式的证书。最近遇到有人提供了jks格式的证书,查阅了几个资料都是需要先将jks转为p12格式,然后再将p12转为crt格式。这里记录一下相关过…

前端国际化之痛点(二):多包多库场景下联动多语言

前言 VoerkaI18n是一款非常优秀的前端国际化解决方案,其开发的出发点是为了解决现存多语言的一些痛点,接下来几篇文章将分别进行分析。 前端国际化之痛点(一):让人头疼的词条Key前端国际化之痛点(二):多包多库场景下联动多语言前端国际化之…

Spark---RDD(双值类型转换算子)

文章目录 1.RDD双值类型算子1.1 intersection1.2 union1.3 subtract1.4 zip 1.RDD双值类型算子 RDD双Value算子就是对两个RDD进行操作或行动,生成一个新的RDD。 1.1 intersection 对源 RDD 和参数 RDD 求交集后返回一个新的 RDD 函数定义: def inters…

公司新买的BI,和金蝶系统配合太默契了

公司一直都用金蝶系统来实现包括财务管理、供应链管理、人力资源管理等多个方面的资源的合理配置和业务流程的自动化。但到了数据分析这块,金蝶系统就明显力不从心,需要一个专业的数据分析工具来接手。财务经理推荐用奥威BI,说这款BI的一大特…

【深度学习】SDXL tensorRT 推理,Stable Diffusion 转onnx,转TensorRT

文章目录 sdxl 转 diffusers转onnx转TensorRT sdxl 转 diffusers def convert_sdxl_to_diffusers(pretrained_ckpt_path, output_diffusers_path):import osos.environ["HF_ENDPOINT"] "https://hf-mirror.com" # 设置 HF 镜像源(国内用户使…

C++11新特性(也称c++2.0)

目录 1.输出C版本&#xff1a;cout << __cplusplus << endl; 2.Uniform Initialization(一致性初始化) 3.initializer_list&#xff08;形参&#xff09; 4.explicit 5.for循环的新用法 6.default和delete 7.Alias Template&#xff08;模板化名&#xff09…