我的编程空间,编程开发者的网络收藏夹
学习永远不晚

什么是伪共享

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

什么是伪共享

这篇文章主要介绍“什么是伪共享”,在日常操作中,相信很多人在什么是伪共享问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”什么是伪共享”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

什么是伪共享

首先大家都知道,随着CPU和内存的发展速度差异的问题,导致CPU的速度远远快于内存,所以一般现在的CPU都加入了高速缓存,就是常说的解决不同硬件之间的性能差异问题。

这样的话,很简单的道理,加入了缓存,就必然会导致缓存一致性的问题,由此,又引入了缓存一致性协议。(如果你不知道,建议去百度一下,这里不做展开)

CPU缓存,顾名思义,越贴近CPU的缓存速度越快,容量越小,造价成本也越高,而高速缓存一般可以分为L1、L2、L3三级缓存,按照性能的划分:L1>L2>L3。

什么是伪共享

而事实上,数据在缓存内部都是按照行来存储的,这就叫做缓存行。缓存行一般都是2的整数幂个字节,一般来说范围在32-256个字节之间,现在最为常见的缓存行的大小在64个字节。

所以,按照这个存储方式,缓存中的数据并不是一个个单独的变量的存储方式,而是多个变量会放到一行中。

我们常说的一个例子就是数组和链表,数组的内存地址是连续的,当我们去读取数组中的元素时,CPU会把数组中后续的若干个元素也加载到缓存中,以此提高效率,但是链表则不会,也就是说,内存地址连续的变量才有可能被放到一个缓存行中。

在多个线程并发修改一个缓存行中的多个变量时,由于只能同时有一个线程去操作缓存行,将会导致性能的下降,这个问题就称之为伪共享。

为什么只有一个线程能去操作?我们举个实际的栗子来说明这种情况:

假设缓存中有x,y两个变量,他们同时已经在不同的三级缓存之中。

这时有两个线程A和B同时去修改位于Core1和Core2的变量x和y。

如果线程A去修改Core1的缓存中的x变量,由于缓存一致性协议,Core2中对应的缓存了x变量的缓存行将会失效,他会被强制从主内存中重新去加载变量。

这样的话,频繁的访问主内存,缓存基本都失效了,将会导致性能的下降,这就是伪共享的问题。

什么是伪共享

如何避免?

既然已经知道了什么是伪共享,那么怎么避免这种情况的发生?

改变行存储的方式?想都别想了。

剩下可行的方法就是填充,如果这一行只有我这一个数据那不就好了吗?

确实就是这样,解决方式通常有以下两种。

字节填充

在JDK8之前,可以通过填充字节的方式来避免伪共享的问题,如下代码所示:

什么是伪共享

自定义填充

一般而言,缓存行有64字节,我们知道一个long是8个字节,填充5个long之后,一共就是48个字节。

而 Java 中对象头在32位系统下占用8个字节,64位系统下占用16个字节,这样填充5个long型即可填满64字节,也就是一个缓存行。

@Contented注解

JDK8以及之后的版本 Java 提供了sun.misc.Contended 注解,通过@Contented注解就可以解决伪共享的问题。

什么是伪共享

注解方式

使用@Contented注解后会增加128字节的padding,并且需要开启-XX:-RestrictContended选项后才能生效。

所以,通过以上两种方式你会发现,对象头大小和缓存行的大小都和操作系统位数有关,JDK的注解帮你解决了这个问题,所以推荐尽量使用注解的方式来实现。

虽然解决了伪共享问题,但是这种填充的方式也浪费了缓存资源,明明只有8B的大小,硬是使用了64B缓存空间,造成了缓存资源的浪费。

而且我们知道,缓存又小又贵,时间和空间的取舍要自己酌情考虑。

实际应用

在Java中提供了多个原子变量的操作类,就是比如AtomicLong、AtomicInteger这些,通过CAS的方式去更新变量,但是失败会无限自旋尝试,导致CPU资源的浪费。

为了解决高并发下的这个缺点,JDK8中新增了LongAdder类,他的使用就是对解决伪共享的实际应用。

LongAdder继承自Striped64,内部维护了一个Cell数组,核心思想就是把单个变量的竞争拆分,多线程下如果一个Cell竞争失败,转而去其他Cell再次CAS重试。

什么是伪共享

Striped64成员变量

解决伪共享的真正的核心就在Cell数组,可以看到,Cell数组使用了Contented注解。

在上面我们提到数组的内存地址都是连续的,所以数组内的元素经常会被放入一个缓存行,这样的话就会带来伪共享的问题,影响性能。

这里使用Contented进行填充,就避免了伪共享的问题,使得数组中的元素不再共享一个缓存行。

什么是伪共享

到此,关于“什么是伪共享”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

什么是伪共享

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

什么是共享存储?

共享存储是一种集中式存储设备,多个系统可共享访问和存储数据。它提高了数据可访问性、简化了管理并提升了性能。主要类型包括NAS(文件级访问)和SAN(块级访问)。共享存储提供数据共享、集中化管理、可扩展性、可靠性和成本效益等优势。其广泛应用于企业、医疗保健、教育、政府和媒体娱乐等行业。选择解决方案时需考虑数据容量、性能、数据保护、可扩展性和成本等因素。
什么是共享存储?
2024-04-02

C++中伪共享的示例分析

这篇文章将为大家详细讲解有关C++中伪共享的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。前言在多核并发编程中,如果将互斥锁的争用比作“性能杀手”的话,那么伪共享则相当于“性能刺客”。“杀手”与“
2023-06-15

mysql共享锁指的是什么

小编给大家分享一下mysql共享锁指的是什么,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!1、说明共享锁,也称读锁,多用于判断数据是否存在,多个读操作可以同时进行
2023-06-15

win10体验共享指的是什么

这篇文章主要介绍“win10体验共享指的是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“win10体验共享指的是什么”文章能帮助大家解决问题。体验共享它是win10新增了的就近共享功能,该功能可
2023-07-01

什么是Spark中的共享变量

在Spark中,共享变量是指在集群中的所有任务之间共享的可变变量。Spark支持两种类型的共享变量:广播变量和累加器。广播变量(Broadcast Variables):广播变量允许程序员在集群中的所有节点上缓存一个只读变量,以便在每个任务
什么是Spark中的共享变量
2024-03-05

php共享内存的方法是什么

在PHP中,可以使用共享内存来实现进程间的通信和数据共享。PHP提供了一个扩展模块,名为shmop,该模块允许我们创建和操作共享内存段。以下是使用shmop扩展模块实现共享内存的基本步骤:1. 创建共享内存段:使用shmop_open函数创
2023-09-06

php中共享内存是什么意思

在PHP中,共享内存是在相同机器中两个正在运行的进程之间共享和传递数据的一种有效方式,该方式允许两个不相关的进程访问同一个逻辑内存,不同进程之间共享同一段物理内存。
2018-11-10

php中共享内存是什么意思

通过PHP的共享内存扩展shmop,可以在不同进程或线程间共享数据,无须进行进程间通信。创建共享内存段需指定唯一键、创建标志和权限模式。使用函数shmop_read()和shmop_write()访问内容,释放时用shmop_close()。适用于高速共享大量数据,如数据缓存和状态共享。优点是速度快,但只适用于同一服务器上的进程或线程。需考虑安全和竞争条件,建议使用唯一键、指定权限和锁定共享内存段。
php中共享内存是什么意思
2024-04-25

win10共享设置的方法是什么

要在Windows 10上设置共享,您可以按照以下步骤操作:1. 打开“设置”应用程序,方法是单击“开始”按钮,然后单击齿轮图标。2. 在“设置”窗口中,选择“网络和Internet”。3. 在左侧导航栏中选择“状态”,然后向下滚动到底部,
2023-08-22

vps多账号共享的方法是什么

VPS多账号共享的方法有以下几种:1. 使用虚拟化技术:使用虚拟化软件,如VMware、VirtualBox等,在VPS上创建多个虚拟机,每个虚拟机有独立的账号和资源配额,可以共享VPS的硬件资源。2. 使用容器化技术:使用容器化平台,如D
2023-09-16

redis实现session共享的方法是什么

这篇文章主要介绍“redis实现session共享的方法是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“redis实现session共享的方法是什么”文章能帮助大家解决问题。引言大厂很多项目都是
2023-07-06

excel共享工作簿的方法是什么

在Excel中,你可以通过以下几种方法来共享工作簿:1. 使用共享功能:点击Excel菜单栏中的“审阅”选项卡,然后选择“共享工作簿”。在弹出的对话框中,选择要共享的工作簿,并设置共享选项,如允许其他用户进行编辑、添加注释等。最后点击“共享
2023-09-12

云服务器共享型是什么意思

云服务器共享型是指多个云服务器可共同提供相同的计算资源和存储资源,以减少单个云服务器使用的资源数量和成本。这种模型通常被称为集群计算,并且与分布式计算有一些相似之处。云服务器共享型提供了一个更大的计算资源池,从而可以降低云服务器使用的成本,同时提高计算资源的利用效率。云服务器共享型的应用主要包括虚拟化应用程序、容器化应用程序、大数据应用程序等。例如,虚拟化应用程序可以将多个云服务器共享成一个虚
2023-10-26

共享IP和独享IP本质上的区别是什么

本篇内容介绍了“共享IP和独享IP本质上的区别是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1.代理IP分为独享IP和共享IP。共享I
2023-06-20

阿里云共享型云服务器是什么

1.什么是阿里云共享型云服务器?阿里云共享型云服务器是一种基于云计算技术的虚拟服务器,它提供了高性能、高可靠性、高可扩展性的计算资源。与传统的物理服务器相比,共享型云服务器具有更高的灵活性和可定制性,可以根据用户的需求进行灵活的配置和管理。2.共享型云服务器的特点2.1高性能共享型云服务器采用了分布式架构,可以提供高性
阿里云共享型云服务器是什么
2024-01-30

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录