缓存一致性协议提供了一种高效的内存数据管理方案,它只会对单个缓存行(缓存行是缓存中数据存储的基本单元)的数据进行加锁,不会影响到内存中其他数据的读写
缓存行是CPU缓存最小存储单元
机械硬盘最小存储单元是簇
缓存一致性协议失效:
1)如果X存储长度大于一个缓存行,也就是变量X数据在一个缓存行中,不能使得X数据的存储空间横跨两个或多个缓存行,否则无法进行加锁,也就是缓存行锁失效,缓存一致性协议无法执行,此时只可以使用总线锁
2)CPU不支持缓存一致性协议
MESI分别代表缓存行数据所处的四种状态
状态 | 描述 | 监听任务 |
M 修改(Modified) | 该Cache line(缓存行)有效,数据被修改了,和内存中的数据不一致,数据只存在于本Cache中 | 缓存行必须时刻监听所有试图读取该缓存行相对就主存的操作,这种操作必须在缓存将该该缓存行写回主存并将状态变为S(共享)状态之前被延迟执行 |
E 独享、互斥(Exclusive) | 该Cache line(缓存行)有效,数据和内存中的数据一致,数据只存在于本Cache中 | 缓存行也必须监听其它缓存读取主存中该缓存行的操作,一旦有这种操作,该缓存行需要变成S(共享)状态 |
S 共享(Shared) | 该Cache line(缓存行)有效,数据和内存中的数据一致,数据存在于很多Cache中 | 缓存行也必须监听其它缓存使该缓存行无效或者对象该缓存行的请求,并将该缓存行需要变成无效(Invalid)状态 |
I 无效(Invalid) | 该Cache line(缓存行)无效 | 无 |
MESI协议只对汇编指令中执行加锁操作的变量有效,表现到java中为使用voliate关键字定义变量或使用加锁操作
工作原理:
CPU1先将主存中X=1(volatile)读取到缓存中同时置为X(E)独占状态,并时刻监听总线中其他CPU对此内存(X=1)的操作
在CPU 缓存还没有回写到主存中时,CPU2也要从主存中将X=1通过总线读取到CPU2缓存中,CPU1通过总线嗅探机制嗅探到CPU2缓存读取了主存X=1,那么此时CPU1将独占状态(E)变为共享状态(S),同时CUP2中也为共享状态(S)
X在CPU1计算后回写到CPU1缓存X=2,准备将X=2通过总线写回到主存中是,先锁定缓存行,将状态变为M(修改,只存在本Cache中),并向总线发消息,由于其他CPU(CPU2)也在监听总线消息,CPU2 嗅探到CPU1发出消息将X变为M(修改)并且将要回写到主存中,此时CPU2将X变为I(无效)。
CPU1 将X写回到主存X=2,然后将CPU1缓存X的状态变为E(独占状态)。
若CPU2还要对X进行访问时需要将CPU2缓存中X(I)清除,然后重新从主存中获取X,此时CPU1、CPU2缓存中X变为S(共享状态)
如果两个CPU同一时间要去修改X状态为M(修改),一个指令周期内进行裁决,假设判为CPU1有效,则置CPU1的X为M(修改),CPU2的X为I(无效),不可能存在两个CPU中的X都为M(状态)
Unsafe是一种原子操作,在裁决失败之后是否继续读取X进行重新操作,取决程序指令是否要求去读取主存中X数据,再次更新再次读取
失效是整个缓存行失效