伪共享问题-并发编程无声的性能杀手
本文以LongAdder源码为例进行说明。关于原子累加器的论述可以参考文章:原子累加器LongAdder与AtomicLong
1.LongAdder部分源码
2.多核机器的存储结构
CPU为了提升性能,在设计上都设计了多级缓存。一个CPU会分多个核心,每个CPU核心都有自己的一级缓存、二级缓存,多个核心之间可以共享三级缓存,多个CPU之间可以共享内存。
时间对比
3.伪共享问题
因为CPU与内存的速度差异很大,需要靠预读数据至缓存来提升效率。而缓存以缓存行为单位,每个缓存行对应着一块内存,一般是64byte(8个long)。缓存的加入会造成数据副本的产生,即同一份数据会缓存在不同核心的缓存行中。CPU要保证数据的一致性,如果某个CPU核心更改了数据,其它CPU核心对应的长高缓存行必须失效。
因为Cell是数组形式,在内存中是连续存储的,一个Cell为24字节(16个字节的对象头和8字节的value),因此缓存行可以存下2个的Cell对象,这样问题就来了:
Core-0 要修改Cell[0]
Core-1 要修改Cell[1]
无论谁修改成功,都会导致对方Core的缓存行失效,比如Core-0中Cell[0]=6000,Cell[1]=8000要累加Cell[0]=6001,Cell[1]=8000,这时会让Core-1的缓存行失效。
总结:缓存系统中是以缓存行(cache line)为单位存储的,当多线程修改互相独立的变量时,如果这些变量共享同一个缓存行,就会无意中影响彼此的性能,这就是伪共享。即由于读写对应同一块内存的缓存行失效,导致的效率降低。
4.伪共享问题的解决方案
@sun.misc.Contended用来解决这个问题,它的原理是在使用此注解的对象或字段的前后各增加128自己大小的padding,从而让CPU将对象预读至缓存时占用不同的缓存行,这样,不会造成对方缓存行的失效。
在对象前后加上间隙,防止占用同一个缓存行,从而避免伪共享。代价就是让对象占用的内存变大了,鱼与熊掌不能兼得。
欢迎大家积极留言交流学习心得,点赞的人最美丽,谢谢
伪共享问题-并发编程无声的性能杀手相关推荐
- 伪共享,并发编程无声的性能杀手
伪共享,并发编程无声的性能杀手 在并发编程过程中,我们大部分的焦点都放在如何控制共享变量的访问控制上(代码层面),但是很少人会关注系统硬件及 JVM 底层相关的影响因素.前段时间学习了一个牛X的高性能 ...
- 伪共享(false sharing),并发编程无声的性能杀手
在并发编程过程中,我们大部分的焦点都放在如何控制共享变量的访问控制上(代码层面),但是很少人会关注系统硬件及 JVM 底层相关的影响因素.前段时间学习了一个牛X的高性能异步处理框架 Disruptor ...
- 并发编程下的性能定律(翻译)
并发编程下的性能定律(翻译) 理解Amdahl定律 如果你想利用多核的优势在尽可能少的时间运行尽可能多的指令,那么就需要以并行的序列分离代码.然而,大多的算法需要运行一些串行代码来调整并行执行.例如, ...
- python和java对比并发_Python并发编程之从性能角度来初探并发编程(一)
本文目录并发编程的基本概念 单线程VS多线程VS多进程 性能对比成果总结 前言 作为进阶系列的一个分支「并发编程」,我觉得这是每个程序员都应该会的. 并发编程 这个系列,我准备了将近一个星期,从知识点 ...
- java 类里面对象共享_Java并发编程 - 对象的共享
编写正确的并发程序,关键问题在于:在访问共享的可变状态时需要进行正确的管理.同步代码块和同步方法可以确保以原子的方式执行操作,同步还有另一个重要的方面:内存可见性. 可见性 为了确保多个线程之间对内存 ...
- java 变量共享_Java并发编程之共享变量
可见性 如果一个线程对共享变量值的修改,能够及时的被其他线程看到,叫做共享变量的可见性. Java 虚拟机规范试图定义一种 Java 内存模型(JMM),来屏蔽掉各种硬件和操作系统的内存访问差异,让 ...
- python多进程内存共享_Python—并发编程04多进程内存共享,python,间,的
Manaegr实现数据共享 导入 :from multiprocessing import Manager 实例化:m= Manager() num = m.dict( {键 : 值} ) num ...
- 伪共享和缓存行填充,Java并发编程还能这么优化!
前言 关于伪共享的文章已经很多了,对于多线程编程来说,特别是多线程处理列表和数组的时候,要非常注意伪共享的问题.否则不仅无法发挥多线程的优势,还可能比单线程性能还差.随着JAVA版本的更新,再各个版本 ...
- 多核编程中伪共享问题(false sharing)
什么是伪共享问题(False Sharing) 在计算机由单核发展到多核之后,多核编程也成为提高性能的利器.每个CPU都有自己的Cache,如果一个内存中的变量在每个cache都存在的话,就需要保证各 ...
最新文章
- Linux shell脚本基础学习详细介绍(完整版)一
- flex 还有人用么_11月LSAT-FLEX:考或不考对今年的申请有什么影响?
- 【BZOJ3160】万径人踪灭 Manacher+FFT
- Qt中多个动态创建的按钮同时绑定一个槽函数,判断被点击的是哪个按钮
- .NET Oracle连接方法
- JS中浮点数运算误差处理
- 张一鸣退一步,换字节跳动的“海阔天空”
- java txt中统计一个字母出现的次数并储存,统计txt文件中每个字符出现的次数,并根据次数从高到低排序...
- NYOJ 93 汉诺塔(三) 【栈的简单应用】
- django基于大数据的应届生求职系统--python-计算机毕业设计
- 账龄分析表excel模板_经理都头疼的财务分析表!新手会计用10套模板半时搞定,厉害...
- zemax---System Explorer(系统选项)
- 三维重建 几何方法 深度学习_基于深度学习的三维重建算法综述
- 解决nf_conntrack: table full, dropping packet
- Python入门——文件读写
- 汉字转换为拼音Java工具类
- 【问题解决】正则表达式在线自动生成器
- 分布式事务Seata源码解析十:AT模式回滚日志undo log详细构建过程
- 【大数据入门核心技术-HBase】(四)HBase2.2.2高可用集群搭建
- python分割字符串为字母_关于python:以大写字母分割字符串