并发编程(七)CPU缓存一致性协议MESI
一、MESI概念
定义:MESI 是指缓存行的四种状态的首字母。
PS:每个缓存行有4个状态,可用2个bit【2位】表示,它们分别是:

二、多核缓存协同操作流程分析
假设有三个CPU A、B、C;对应三个缓存分别是缓存A、B、 C;并在主内存中定义了x的引用值为0。

1、单核读取

2、双核读取

3、修改数据

4、同步数据

三、缓存行伪共享
什么是伪共享?
CPU缓存系统中是以缓存行为单位存储的,目前主流的CPU Cache 的缓存行大小都是64Bytes。
定义:在多线程情况下,如果需要修改共享同一个缓存行的变量,就会无意中影响彼此的性能,这就是伪共享。
举个🌰:现在有2个变量 a 、b,如果有线程t1在访问a,线程t2在访问b,而a与b刚好在同一个缓存行中,此时t1先修改a,将导致b被刷新!
怎么解决伪共享?
解决方式:@sun.misc.Contended注解【JDK1.8+】
作用:加上这个注解的类会自动补齐缓存行,类前加上代表整个类的每个变量都会在单独的缓存行中。
PS:需要在jvm启动时设置 -XX:-RestrictContended 才会生效。
四、小问答
Q:为什么java等高级语言相对会运行慢一些?
因为代码经历2次转换才到CPU进行执行:
- 1、经历了jvm内置的翻译器把字节码翻译成汇编指令【时间相对长一点】(软件层面的工作)
- 2、汇编指令要转换成二进制编码【很快】(硬件层面的工作)
PS:硬件具有硬编码的能力,可以实现汇编指令【硬件原语】----->二进制编码的转换
Q:为什么硬件缓存锁定机制会使用两种?
首先我们理解一下以下概念:
- 缓存锁的产生:class文件被JVM解析以后转换成的汇编指令中的Lock前缀触发的。
- 缓存锁分类:1️⃣总线锁、2️⃣缓存一致性协议
原因:早期受技术制约所以使用总线锁保证缓存一致【缺陷:锁了总线其他CPU没法访问内存,无法发挥多核并行的优势导致性能低下】,后期进行技术改进后设计出了MESI缓存一致性协议模型。
PS:若一个对象大小超过了64字节时【一个缓存行装不下】,那么缓存一致性协议就会变成总线锁的形式。
PS:单个缓存行可以通过缓存锁保证原子性,但当对象大小超过一个缓存行大小时,则无法通过锁定缓存行来保证原子性了,即此时MESI方式锁缓存行行不通。

浙公网安备 33010602011771号