CPU多级缓存(总线锁/缓存行/MESI)
2021-02-25 23:26:48 4 举报
AI智能生成
CPU多级缓存(总线锁/缓存行/MESI)
作者其他创作
大纲/内容
CPU架构
存储层次结构(金字塔)
寄存器 → L1缓存 → L2缓存 → L3缓存 → 主内存 → 本地磁盘 → 远程数据库
越往上访问速度越快、成本越高,空间更小。越往下访问速度越慢、成本越低,空间越大
多级缓存
为什么要设置多级缓存?
为了解决CPU运算速度与内存读写速度不匹配的矛盾
多级缓存的工作原理
在CPU和内存之间,引入了L1高速缓存、L2高速缓存、L3高速缓存
每一级缓存中所存储的数据全部都是下一级缓存中的一部分
每一级缓存中所存储的数据全部都是下一级缓存中的一部分
当CPU需要数据时,先从缓存中取,加快读写速度,提高CPU利用率
总线锁和缓存锁
总线锁
锁住总线,通过处理器发出lock指令,总线接受到指令后,阻塞其他处理器的请求,
直到此处理器执行完成。这样该处理器就可以独占共享内存的使用
直到此处理器执行完成。这样该处理器就可以独占共享内存的使用
缺点:一旦某个处理器获取总线锁,其他处理器都只能阻塞等待,影响多核处理器的性能
缓存锁
不锁总线,只锁住被缓存共享的对象(缓存行)
缓存锁也不是万能,有些场景和情况依然必须通过总线锁才能完成
缓存行(cache line)
为了压榨CPU的性能,一次获取一整块的内存数据(64个字节)放入缓存
为什么是
64字节?
64字节?
与CPU架构有关,通常有32字节、64字节、128
字节不等。目前64位架构下,64字节最为常用
字节不等。目前64位架构下,64字节最为常用
设置的太小了,读取速度快,但命中率太低
设置的太大了,命中率很高,但读取速度慢
伪共享问题
多核多线程并发场景下,如果多核要操作的共享变量处于
同一缓存行,某CPU更新该缓存行中的数据,会导致其他
处理器缓存中的缓存行失效,每次用还要去主存重新加载
同一缓存行,某CPU更新该缓存行中的数据,会导致其他
处理器缓存中的缓存行失效,每次用还要去主存重新加载
解决方案:字节填充
字节填充
long在java中占用8字节,在其前后额外填充7个long类型的变量
将目标变量放入缓存行时,可以实现一个缓存行中只有目标变量
将目标变量放入缓存行时,可以实现一个缓存行中只有目标变量
缓存一致性协议
当多个处理器都涉及同一块主内存区域的更改时,将导致各自的的缓存数据不一致,为了解决这个问题
所以提出了缓存一致性协议,这类协议有 MSI、MESI、MOSI等,其中最常见的就是 Intel 的MESI 协议
所以提出了缓存一致性协议,这类协议有 MSI、MESI、MOSI等,其中最常见的就是 Intel 的MESI 协议
MESI协议
MESI 协议是四种状态的缩写,用来修饰缓存行的状态(在每个缓存行前额外使用2bit,来表示这四种状态)
监听(嗅探)机制
M 已修改
Modified
Modified
该缓存行的数据被修改了,和主存数据不一致
监听所有想要修改此缓存行对应的内存数据的操作,该操作必须等缓
存行数据更新到主内存中,状态变成 S (Shared)共享状态之后执行
存行数据更新到主内存中,状态变成 S (Shared)共享状态之后执行
E 独占
Exclusive
Exclusive
该缓存行和内存数据一致,数据只在本缓存中
监听所有读取此缓存行对应的内存数据的操作,如果发生这种操作,
Cache Line 缓存状态从独占转为共享状态
Cache Line 缓存状态从独占转为共享状态
S 共享
Shared
Shared
该缓存行和内存数据一致,数据位于多个缓存中
监听其他缓存使该缓存行失效或者独享该缓存行的操作,如果检测到
这种操作,将该缓存行变成无效
这种操作,将该缓存行变成无效
I 失效
Invaild
Invaild
该缓存行的数据无效
没有监听,处于失效状态的缓存行需要去主存读取数据
JMM
Java内存模型即Java Memory Model,用来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各平台下都能够达到一致的内存访问效果
通俗来讲,每个线程都有自己的工作内存(本地内存),线程之间的共享变量存储在主内存,工作内存中存储
了共享变量的副本,不同线程之间无法直接访问对方工作内存中的变量,线程间的通信均需要在主内存完成
了共享变量的副本,不同线程之间无法直接访问对方工作内存中的变量,线程间的通信均需要在主内存完成
再通俗点
工作内存 = 虚拟机栈
主内存 = 堆区 + 方法区
0 条评论
下一页