CPU缓存一致性协议MESI
cpu为甚要有高速缓存
就是为了解决io速度与cpu运算速度直接不匹配的问题
时间局部性:一个信息正在被访问,那么再近期它可能还会被再次访问一并取出来
空间局部性: 一个信息在存储器的位置被引用,会将它附近位置也被引用
带有缓存的cpu执行计算的流程
1.程序以及数据被加载到主内存中
2.指令和数据被加载到cpu的高速缓存
3.cpu执行指令,把结果写到高速缓存中
4.高速缓存中的数据写回主内存中
jvm-jmm-cpu执行流程
1.编写的.java文件通过ClassLoader编译成.class文件(详细如何在主存分配jvm会详细解释的)(编译期)
2.将字节码解释成汇编语言(解释期)
注意;现在比较常见的一款jvm是HotSpot的,这款jvm为了要和c/c++程序一较高下,采用了JIT(just in time)即时编译,采用的是解释器和即时编译器并存的架构,不必等待即时编译器全部编译完成再执行,而且还具备热点探测功能(这部分不详细展开,后期还会出jvm相关的知识点)
3.汇编指令回最终转换机器指令(0和1)
4.再将其加入到缓存,cpu执行,cpu中寄存器充当数据的保存。
目前主流的多级缓存结构
常见的三级缓存
模式图
一个现代cpu的完整概貌如图所示
目前cpu都是多核cpu,如何确保内部数据的一致,不让系统数据混乱,这里就引出了一个一致协议MESI。
MESI协议缓存4种状态
M修改
E独享
S共享
I无效
MESI状态转换
这幅图具体意思会通过下面例子进行讲解:
cpuA和cpuB同时对主存中的某个变量进行读取和修改
cpuA发出一条指令,从主存中读取X
cpuA从内存中通过总线读取到cache a中并将状态设置为E
cpuB发出一条指令,从主存中读取X
cpuB发出一条指令,从主存中读取X
cpuB试图从主存中读取X时,cpuA检测到了地址冲突。这时cpuA相关数据做出响应。此时x存储于cache a和cache b中,x在cache a和cache b中都设置为S
修改数据
cpu A计算完了发出修改x的指令
cpuA将x设置为M状态并通知缓存了X的cpuB,cpuB将本地cache b的x设置为I状态
cpuA进行赋值
同步数据:
cpu B发出了要读取X的指令
cpu B通知cpu A,cpuA将修改后的数据同步到主内存中时cache a修改为E
cpu A同步cpu B的x,将cache a和同步后cache b中的x设置为S
其实这里面还有很多有趣的事情:
cpuA在修改x后,会将其他持有x的cpu让它失效,如果cpu多,这地方会严重降低cpu的性能,可以设置个存储缓存,让cpu干其他事情去,当所有失效确认后,cpu再过来执行。
同样, 存在问题:如:cpu还没有写入缓存中,但是其他cpu就开始进行读取,这时候的value值肯定不对的等等,其实cpu底层还是很复杂的,但是那些大佬也有相应的方案进行解决。