CPU层面的缓存一致性问题分析

CPU层面的缓存一致性问题分析

参考文章:小林coding的图解操作系统,讲的很好,计网和操作系统和数据库都有图解,强推。https://xiaolincoding.com/os/

CPU的缓存行为是什么?

请添加图片描述
由图,越靠近CPU的存储器CPU的访问速度越快,当然容量更小,造价更高,其中L1,2,3就代表了CPU的缓存结构,集成在CPU内部,L1级缓存可以分为数据缓存和指令缓存,然后是L2,L1和L2都是每个CPU核心分配一份,L3缓存是核心之间共享的

当CPU需要某个数据时,会从上往下依次查询,当查询到会返回,并将其进行进一步缓存,如果可以的话,这样做主要是为了弥补CPU访问内存时间和CPU计算素的之间的差异

CPU L1 Cache 随机访问延时是 1 纳秒,内存则是 100 纳秒,所以 CPU L1 Cache 比内存快 100 倍左右。SSD 随机访问延时是 150 微秒,所以 CPU L1 Cache 比 SSD 快 150000 倍左右。可见缓存的重要性

CPU如何找到内存地址对应的缓存?

CPU 怎么知道要访问的内存数据,是否在 Cache 里?如果在的话,如何找到 Cache 对应的数据呢?

简单策略:直接映射(Direct Mapped Cache)
CPU读取数据是以内存块为单位的,读取时需要知道内存块的地址,采用直接映射时(模运算),就是将内存块的地址直接映射缓存地址,这就类似于哈希算法,当然就会出现哈希冲突,所以缓存内存块的时候还会带上组标记,查询缓存时还需要判断缓存的是不是同一组的数据,因为可能发生过哈希冲突而覆盖掉了。

CPU缓存写入操作如何执行?

1.写直达:执行写操作时,不管缓存中有没有都会把数据写入内存,修改缓存,如果有缓存的话,但是这样相当于每次都需要访问内存,这就降低了CPU速度

2.写回:当发生写操作时,仅仅修改缓存块中的数据并且标记缓存块为脏块(dirty),只有当别的内存块覆盖掉当前块后,发现它是脏块,才会把它写入内存中,减少了写回内存的次数,提高效率。

拓展:在写回策略中,如果数据还没有被缓存,为什么要先把他缓存后再修改,而不是直接修改内存?

原因是因为要保证缓存一致性,根据MESI协议,修改时标记缓存为独占,并标记其他核心该缓存为失效,这样保障了缓存一致性,而且效率较高,所以先把数据缓存起来,是为了通知其他核心不要对其进行修改(通过广播使其他核心的该缓存设置为失效)

CPU的缓存一致性问题

现代的CPU都是多核的

出现缓存一致性的场景:例如某个CPU的两个核心,每个核心都有自己的L1/L2缓存,L3缓存在核心之间共享,当某个核心执行写操作时,修改某个数据时,先将其装入缓存,再修改缓存块,这时候内存数据仍然是旧数据,直到缓存块被覆盖时,才会将其写回内存中,这就会造成另个一核心获取数据时获取到内存中的旧值

所以要保证缓存一致必须满足两点要求:

  • 写传播:一个核心缓存块的修改,必须传播到其他核心的缓存块中
  • 事务串行化:一个改200,一个改成300,两种修改传播到第三个核心时,如果先变200,再变300,最终为300,而如果传播顺序反转,就会修改成200,所以需要保证传播的顺序(就需要使用锁机制来实现串行了)

接下来就来看看这两个要求具体是如何实现的?

总线嗅探

写传播的原则就是当某个 CPU 核心更新了 Cache 中的数据,要把该事件广播通知到其他核心

当某个核心修改了某个缓存块的数据,会把这种修改通过总线进行广播,每个CPU都去看看自己有没有缓存该块,如果缓存了,就也进行修改

但是这样做每个核心都需要做一遍这个操作,而核心可能并没有缓存该数据,加重CPU工作,加大的总线的负载,而且此方法只能解决第一点写传播的要求,并不能满足第二点的事务串行化

MESI 协议

MESI 协议其实是 4 个状态单词的开头字母缩写,分别是:

  • Modified,已修改
  • Exclusive,独占
  • Shared,共享
  • Invalidated,已失效

当缓存是独占状态时,说明只有当前核心缓存了数据,就不需要担心缓存一致性问题,当其他线程进来缓存了该数据时,就会变成共享状态。

这时候想修改数据,第一步是先通过广播把其他核心的该缓存设置为失效,再进行修改

所以,可以发现当 Cache Line 状态是「已修改」或者「独占」状态时,修改更新其数据不需要发送广播给其他 CPU 核心,这在一定程度上减少了总线带宽压力。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

踢足球的程序员·

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

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

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

打赏作者

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

抵扣说明:

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

余额充值