电子说
介绍
之前介绍了java并发包的cas原理和java内存模型,这篇我们介绍下cpu缓存一致性原理,可以帮助我们更好的理解cas的底层原理。
一、cpu多级缓存结构
计算机在寄存器上执行的速度是远大于在主内存上执行的速度。
由于计算机的存储设备与处理器的运算速度之间存在几个数量级的差距,所以新的计算机系统都不得不加入一层读写速度都尽可能接近处理器运算速度的高级缓存来作为内存与处理器之间的缓冲,将运算使用到的数据复制到缓存中,让运算快速执行,当运算结束后,再将数据从缓存同步到内存中,这样处理器就无需等待缓慢的内存读写了。
一个计算机还包含一个主存,所有的cpu都可以访问这个主存,主存通常比CPU中的缓存大得多。
多核cpu运作原理:
通常情况下,当一个CPU需要读取主存的时候,它会将主存的数据读取到CPU缓存中,甚至会将缓存中的部分内容读到它内部的寄存器里面,然后在寄存器中执行操作;当CPU需要将结果回写到主存的时候,它会将内部寄存器的值刷新到缓存中,然后在某个时间点将值刷新回主存。
二、MESI协议
四种状态:
M:Modified(被修改)
指的是该缓存行只被缓存在该CPU的缓存中,并且是被修改过的,因此它与主存中的数据是不一致的,该缓存行的内存需要在未来的某个时间点写回主存,这个时间点我们是允许其他CPU读取主存中相应的内存之前,当这里的值被写回主存之后,该缓存行的状态变成E。
E:Exclusive(独享)
独享状态的缓存行只被缓存在该CPU的缓存中,它是未被修改过的,是与主存中的数据一致的,这个状态可以在任何时刻,当有其他CPU读取该内存时变成S。同样的,当COU修改该缓存行的数据时,该状态可以变成M。
S:Shared(共享)
共享状态意味着,该缓存行可能被多个CPU进行缓存,并且各个缓存中的数据与主存中的数据是一致的,当有一个CPU修改该缓存行的时候,其他CPU中该缓存行是可以被作废的,变成I。
I:Invalid(无效的)
无效状态代表这个缓存是无效的,可能是有其他CPU修改了该缓存行。
CPU的cache的四种操作可能产生不一致的状态,因此缓存控制器监听到本地操作和远程操作的时候,需要对地址一定的cache line做出一定的修改,从而保证数据在多个缓存之间的一致性。
四种操作:
local read
代表的是读本地缓存行中的数据。
local write
代表的是将数据写入到本地的缓存里面。
remote read
代表的是将内存中的数据读取到本地。
remote write
代表的是将数据写回到主存中。
三、MESI工作原理
在一个典型的多核系统中,每一个核都会有自己的缓存来共享主存总线,每一个相应的CPU都会发出读写请求,而缓存的目的是为了减少CPU读写共享主存的次数。
因此对于M和E,它的数据总是精确的,而S状态可能是非一致的,如果一个缓存将处于S状态的缓存行作废了,另一个缓存实际上可能已经独享了该缓存行,但是该缓存却不会将缓存行变更为E状态,这是因为其他缓存不会广播他们作废掉该缓存行的通知,同样,由于缓存并没有保存该缓存行的topic数量,因此也没有办法确认自己是否已经独享了该缓存行。
如果一个CPU想修改处于S状态的缓存行,总线事务需要将所有该缓存行topic的值变成Invalid状态才可以,而修改E状态的缓存不需要使用总线事务。
四、MESI在并发包中的应用
在cas原理分析中,我们讲到cas底层原理使用到了总线锁和缓存锁,其中缓存锁涉及到的就是MESI协议,缓存锁加锁条件就是缓存行处于M和E状态下。
下面结合volatile保证内存可见性为例,阐释下MESI的工作原理。代码示例:
public class VolatileCanSeeTest {
private static boolean initFlag = false;
public static void main(String[] args) throws InterruptedException {
new Thread(() - > {
log.info("init begin");
while(!initFlag) {
}
// if(!initFlag) {while(true){}} // JIT
log.info("===success===");
}).start();
Thread.sleep(1000);
new Thread(() - > doSomething()).start();
}
public static void doSomething() {
log.info("doSomething begin");
initFlag = true;
log.info("doSomething end");
}
}
结语
上一篇我们分析了java内存模型的原理,这篇总结下cas涉及到的cpu缓存一致性协议,通过这两篇的介绍,我们就可以更深刻的理解cas是怎么保证原子性的。
全部0条评论
快来发表一下你的评论吧 !