CPU多核并发缓存架构
CPU工作原理
- 首先CPU工作的时候,由控制单元充当大脑,负责协调。
- 让运算单元做运算的时候,会首先从最靠近CPU的寄存器(其实是和CPU一体的)上读取数据,在寄存器上有CPU运行的常用指令
- 如果寄存器上没有想要的数据,则就从三级缓存的L1级缓存中获取,如果L1取到数据了,会加载到寄存器中,再转输给CPU运算单元。
- 如果L1中没有,则从L2级缓存中读取,同理,如果没有,则从L3中取。
- 如果L3中也没有,这个时候,就比较麻烦了。要从主内存中取。
- 而从主内存中取的时候,会经过系统总线及内存总线,这时因受到总线的限制,速度会大大降低。而且会存在众多问题。
为什么要加入缓存
从主内存中取的时候,会经过系统总线及内存总线,这时因受到总线的限制,速度会大大降低。而且会存在众多问题。读入缓存,下次用时从缓存读取,效率会大大提高
如何解决缓存不一致性问题?
为是什么会不一致?
- 如果cpu1改变了从主内存中读取的一个数据,而cpu2也刚好访问同一块区域也需要读取这个数据,那么读到的就会是未改变的值,造成缓存不一致
那么为了解决一致性的问题,需要各个处理器访问缓存时都 遵循一些协议,在读写时要根据协议来进行操作。常用的方法是总线加锁或是缓存一致性协议-MESI
什么是缓存一致性协议MESI
MESI代表的四种状态:
-
M:修改
-
E:独享。互斥
-
S:共享
-
I:无效
MESI缓存一致性协议原理:
- 假如现在有
CPU1和CPU2,主内存有变量X= 1
。现在要做 x+1的操作。 - 如果
在变量 x = 1 上加上volatile
,则就会触发MESI - 当CPU1从主内存中读取到X=1时,CPU1会把此变量标记成独享状态
- 并监听总线,是否有其它CPU去读取此变量
- 当CPU2从主内存中读取X=1变量时,CPU1会通过
嗅探机制
监听到。 - 此时CPU1的X变量会变成共享状态。继续进行计算,计算完变成X=2。
- 此时要回
写到主内存之前。先锁住缓存行
。并标记X变量为修改状态。并向总线发消息。 - 其它
CPU2监听总线时,会监听到,并把X标记成无效状态
。 - CPU1把变量X=2回写到主内存后,会由
修改状态变成独享状态
。 - 此时,
如果CPU2如果想修改X变量时,要重启从主内存中读取。
然后开始新的轮回。
指令重排序
–为了使得处理器内部的运算单元能尽量被充分利用,处理器可能会对输入代码进行乱序执行(Out-Of-Order Execution)优化,处理器会在计算之后将乱序执行的结果重组,保证该 结果与顺序执行的结果是一致的,但并不保证程序中各个语句计算的先后顺序与输入代码中的 顺序一致
。因此,如果存在一个计算任务依赖另一个计算任务的中间结果,那么其顺序性并不 能靠代码的先后顺序来保证。
与处理器的乱序执行优化类似,Java虚拟机的即时编译器中也有 类似的指令重排序(Instruction Reorder)优化