对于CPU缓存一致性及有序性-努力学习Java的小白

X度一面被共享到了基础架构,顿时压力上来了
这玩意也不懂啊,然后问了一道操作系统问题,脑子一片空白
没错,问的就是CPU缓存一致性和有序性的实现
可能是Java并发看多了,第一想法,难道是volatile来修饰变量让线程副本来保证数据可见性,CPU会不会也一样,毕竟线程一般都和CPU进行捆绑嘛,然后遭到了否
面试完后仔细看操作系统,发现了华点
由于CPU L1/L2 cache是cpu独有的,L3是多CPU中共享的,那么不同CPU中L1/L2对于内存中同一个数据进行操作,如果没有什么手段,必然会造成数据不一致。
先给出一个概念CPU cache的数据写入时机,分为了写直达和写回
(来说明一下这两者
写直达
把数据同时写入内存和cache中,来保证内存和cache的一致性
在写入之前判断,如果数据已经在cache里,先将数据更新到cache里,再写入到内存里
如果数据没有在cache里,就直接把数据更新到内存里
but,不管数据在不在cache里,这样操作都会写入到内存中,相比cpu cache block而言还是会花费大量时间
写回
当发生写操作时,新的数据仅仅被写入cache block里,只有当修改过的cache block被替换的时候才需要到内存
即进行写操作时,数据在cup cache里的话,直接更新到cpu cache里,同时标记该cache block为脏(突然就想到了MySQL中缓存页的脏页了),cpu cache里面的cache block的数据和内存是不一致的(因为还没更新到内存),这种情况不用把数据写到内存里
如果cache block里放的是别的内存地址的数据,就要先检查cache block里数据有没有标记为脏的,如果是脏,则先写回内存再拿出来更新再标记脏
不是脏的,则直接写入cache block中再标记为脏就ok
如何解决CPU缓存一致性呢?
1、写传播:某个CPU核心里的cache数据更新时,必须要传播到其他核心cache
2、事务的串行化:某个cpu核心里对数据操作顺序,必须在其他核心看起来顺序一样
对于写传播的实现方式:总线嗅探
相信通信专业应该都知道cdma,我感觉比较类似,相当于监听数据总线,如果有cpu对数据进行了更新,那么其他cpu通过广播也接收该消息
对于事务串行化的实现方式:内存屏障
是不是在哪里还见过它?没错,就是volatile,通过内存屏障来防止指令重排序,保证有序性
根据上述两点能够组成缓存一致性协议,在此列举一下MESI协议:
M:Modify 已修改
E:Exclusive 独占
S:shared 共享
I:invalidated 已失效
四个状态来标记cache line状态
已修改:就是脏标记,代表cache block中数据已更新过,但是没到内存中
已失效:cache block里数据已经失效了,不可以读取
独占和共享:标识cache block里数据是干净的即这cache block里数据和内存的数据是一致性
独占状态:数据只在一个CPU核心的cache里,其他cpu没有该数据,所以不需要担心一致性
共享状态:相同的数据在多个CPU的cache里都有,所以要修改时,对所有cpu核心广播请求,其他核心要将cache中cache line标记为无效状态,然后再更新数据

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一十无乘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值