文章目录
- 概念
- MESI协议中的状态
- MESI协议中的问题及方案
- 总结
概念
MESI
(Modified Exclusive Shared Or Invalid
)(也称为伊利诺斯协议,是因为该协议由伊利诺斯州立大学提出)是一种广泛使用的支持写回策略的缓存一致性协议。
MESI协议中的状态
CPU
中每个缓存行(caceh line
)使用4种状态进行标记(使用额外的两位(bit
)表示):
M: 被修改(Modified)
该缓存行只被缓存在该CPU
的缓存中,并且是被修改过的(dirty
),即与主存中的数据不一致,该缓存行中的内存需要在未来的某个时间点(允许其它CPU
读取请主存中相应内存之前)写回(write back
)主存。
当被写回主存之后,该缓存行的状态会变成独享(exclusive
)状态。
E: 独享的(Exclusive)
该缓存行只被缓存在该CPU
的缓存中,它是未被修改过的(clean
),与主存中数据一致。该状态可以在任何时刻当有其它CPU
读取该内存时变成共享状态(shared
)。
同样地,当CPU
修改该缓存行中内容时,该状态可以变成Modified
状态。
S: 共享的(Shared)
该状态意味着该缓存行可能被多个CPU
缓存,并且各个缓存中的数据与主存数据一致(clean
),当有一个CPU
修改该缓存行中,其它CPU
中该缓存行可以被作废(变成无效状态(Invalid
))。
I: 无效的(Invalid)
该缓存是无效的(可能有其它CPU
修改了该缓存行)
I: MESI转态流转图
MESI协议中的问题及方案
伪共享(Flase Sharing)
问题定义
当我们访问一个数据时,获取一个数据后,其相邻的值也会被缓存到就近的缓存行中,比如访问一个int类型的数据时候,其他额外的60个字节的数据也会被加载到缓存行中,CPU缓存行一般是32/64个字节加载数据的,不论当前线程是否使用这个数据。
但是这种模式在多核模式下,比如A,B两个线程访问的数据在同一个缓存行中,就会存在A,B两个线程会频繁的刷新当先线程不需要的数据,导致效率下降。
问题解决
1padding对齐
padding:在java中,为了能够更加高效的利用内存空间,会将对象大小设定为8bytes的整数倍,如果对象头+实例数据的大小不是8bytes的倍数,那么会在padding区域填充几个字节,使得对象占用空间是8bytes的倍数
2.注解
在JDK1.8中,新增了一种注解**@sun.misc.Contended**,来使各个变量在Cache line中分隔开。
注意,jvm需要添加参数**-XX:-RestrictContended**才能开启此功能 。类前加上代表整个类的每个变量都会在单独的cache line中。属性前加代表该属性会在单独的cacheline中
总结
MESI 协议,是已修改、独占、共享、已失效这四个状态的英文缩写的组合。整个 MSI 状态的变更,则是根据来自本地 CPU 核心的请求,或者来自其他 CPU 核心通过总线传输过来的请求,从而构成一个流动的状态机。另外,对于在「已修改」或者「独占」状态的 Cache Line,修改更新其数据不需要发送广播给其他 CPU 核心。