了不起:又到了每天一到面试题的试题时候了!学弟,每天最近学习的道面怎么样啊
了不起学弟:最近学习的还不错,每天都在学习,试题每天都在进步!每天
了不起:那你最近学习的道面什么呢?
了不起学弟:最近在学习CPU伪共享,但是试题不太理解,能不能给我讲讲呢?
首先,我们先了解一下CPU的缓存模型。
CPU的缓存分为三层,一级缓存,二级缓存,三级缓存。
如果要获取一个内存中的数据,首先会从一级缓存中获取,如果一级缓存中没有,就会从二级缓存中获取,如果二级缓存中没有,就会从三级缓存中获取,如果三级缓存中没有,就会从内存中获取。
一级缓存是最快的,越到后面就越慢。那CPU的缓存,是由缓存行组成的,每个缓存行的大小是64字节,也就是说,如果我们要获取一个数据,那么就会把这个数据所在的内存地址,以及这个数据所在的内存地址的前后64字节的数据,都会加载到缓存行中。
聊到这里,我就给大家看看常见的伪共享问题的案例。
假设有两个线程a和b,同时有两个long类型的变量A和B。两个变量都是互相紧挨着的。那线程a要去操作A,就会把变量A和B一起带入的缓存行,线程b要去操作变量B,也会同时把AB带入缓存行。此时如果线程a把A做了修改,再通过BUS总线进行了通知,内存再做了修改。线程b重新从内存获取变量B,那么此时这种还需要从内存获取变量,这就是伪共享了。
伪共享:变量AB毫不相关,但是一旦其中一个变量被修改,另一个变量也会被重新加载。
伪共享的解决方案:
举例:
private static class Padding{ private volatile long a; public volatile long a1,a2,a3,a4,a5,a6,a7; private volatile long b; }
2.使用@Contened注解在变量上,同时在jdk8中还需要在jvm启动参数中加入-XX:-RestrictContended,jdk8以上的版本就不需要这个参数即可,这样就可以解决伪共享的问题了。
private static class Padding{ @Contended private volatile long a; @Contended private volatile long b; }
今天就给大家分享了一下关于CPU伪共享的问题,大家如果对CPU缓存模型那块还有疑问,可以多查找一下资料,比如MESI缓存一致模型等等。
责任编辑:武晓燕 来源: Java面试教程 内存缓存缓存(责任编辑:休闲)
和泓服务(06093.HK)年度净利5635.7万元 每股基本盈利为12.76分
今年首份“兜底式增持”倡议引起市场关注 投资者应理性看待收益和风险
香雪制药(300147.SZ):Athenex口服紫杉醇新药申请暂未获FDA批准
江山欧派(603208.SH)公布消息:公开发行可转债申请获审核通过
一季度互联网企业业务收入同比增长28.7% 生产、生活类服务平台快速恢复