CPU缓存一致性协议MESI

cpu为甚要有高速缓存

就是为了解决io速度与cpu运算速度直接不匹配的问题

时间局部性:一个信息正在被访问,那么再近期它可能还会被再次访问一并取出来

空间局部性: 一个信息在存储器的位置被引用,会将它附近位置也被引用

带有缓存的cpu执行计算的流程

java me是什么 java mesi_缓存


1.程序以及数据被加载到主内存中

2.指令和数据被加载到cpu的高速缓存

3.cpu执行指令,把结果写到高速缓存中

4.高速缓存中的数据写回主内存中

jvm-jmm-cpu执行流程

java me是什么 java mesi_java me是什么_02


1.编写的.java文件通过ClassLoader编译成.class文件(详细如何在主存分配jvm会详细解释的)(编译期)

2.将字节码解释成汇编语言(解释期)

注意;现在比较常见的一款jvm是HotSpot的,这款jvm为了要和c/c++程序一较高下,采用了JIT(just in time)即时编译,采用的是解释器和即时编译器并存的架构,不必等待即时编译器全部编译完成再执行,而且还具备热点探测功能(这部分不详细展开,后期还会出jvm相关的知识点)

3.汇编指令回最终转换机器指令(0和1)

4.再将其加入到缓存,cpu执行,cpu中寄存器充当数据的保存。

目前主流的多级缓存结构

常见的三级缓存

java me是什么 java mesi_数据_03


模式图

java me是什么 java mesi_开发语言_04


一个现代cpu的完整概貌如图所示

java me是什么 java mesi_缓存_05

目前cpu都是多核cpu,如何确保内部数据的一致,不让系统数据混乱,这里就引出了一个一致协议MESI。
MESI协议缓存4种状态
M修改
E独享
S共享
I无效

MESI状态转换

java me是什么 java mesi_缓存_06

这幅图具体意思会通过下面例子进行讲解:

cpuA和cpuB同时对主存中的某个变量进行读取和修改

java me是什么 java mesi_开发语言_07


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

java me是什么 java mesi_java me是什么_08


修改数据

cpu A计算完了发出修改x的指令

cpuA将x设置为M状态并通知缓存了X的cpuB,cpuB将本地cache b的x设置为I状态

cpuA进行赋值

java me是什么 java mesi_java_09


同步数据:

cpu B发出了要读取X的指令

cpu B通知cpu A,cpuA将修改后的数据同步到主内存中时cache a修改为E

cpu A同步cpu B的x,将cache a和同步后cache b中的x设置为S

java me是什么 java mesi_开发语言_10


其实这里面还有很多有趣的事情:

cpuA在修改x后,会将其他持有x的cpu让它失效,如果cpu多,这地方会严重降低cpu的性能,可以设置个存储缓存,让cpu干其他事情去,当所有失效确认后,cpu再过来执行。

同样, 存在问题:如:cpu还没有写入缓存中,但是其他cpu就开始进行读取,这时候的value值肯定不对的等等,其实cpu底层还是很复杂的,但是那些大佬也有相应的方案进行解决。