CPU缓存基础知识(二)|Java 开发实战

216 阅读4分钟

目录结构

一、CPU缓存基础知识

二、缓存命中

三、缓存的一致性

四、典型用例

五、队列伪共享

image

前言导读

基本上cpu缓存知识是进入大厂的一个基本知识点了,而且也相当看重,这部分的知识掌握的比较好的话,会很加分的!

说下历史:

在计算的前几十年中,主内存非常慢且昂贵得令人难以置信,但是CPU也不是特别快。从1980年代开始,差距开始迅速扩大。微处理器的时钟速度飞速发展,但是内存访问时间的改善远没有那么明显。随着这种差距的扩大,越来越明显的是需要一种新型的快速存储器来弥合这种差距。

CPU缓存基础知识(一)

今天分享的是缓存一致性和缓存命中

缓存一致性

部分来自维基百科:

为了和下级存储(如内存)保持数据一致性,就必须把数据更新适时传播下去。这种传播通过回写来完成。一般有两种回写策略:写回(Write back)和写通(Write through)。

根据回写策略和上面提到的未命中的分配策略,请看下表

image

通过上图,我们知道:

写回时:如果缓存命中,不用更新内存,为的就是减少内存写操作,通常分配策略是分配

  • 怎么标记缓存在被其他cpu加载时被更新过?每个Cache line提供了一个脏位(dirty bit)来标识被加载后是否发生过更新。(cpu在加载时是一块一块加载的不是一个字节一个字节加载的,前面说过)

  • image

写通

  • 写通是指,每当缓存接收到写数据指令,都直接将数据写回到内存。如果此数据地址也在缓存中,则必须同时更新缓存。由于这种设计会引发造成大量写内存操作,有必要设置一个缓冲来减少硬件冲突。这个缓冲称作写缓冲器(Write buffer),通常不超过4个缓存块大小。不过,出于同样的目的,写缓冲器也可以用于写回型缓存。

  • 写通较写回易于实现,并且能更简单地维持数据一致性。

  • 通常分配策略是非分配

对于一个两级缓存系统,一级缓存可能会使用写通来简化实现,而二级缓存使用写回确保数据一致性

MESI协议:

这里有一个网页这个地址太6x了,参考了很多资料,还是不如动画嗄。。。。www.scss.tcd.ie/Jeremy.Jone…

建议先玩一玩上面网址的动图,可以了解下,各个cpu的缓存和主存的读、写数据。

这里简单阐述一下:我们主存有个x=0的值,处理器有两个cpu0,cpu1

  • cpu0读x的值,cpu0先在cpu0缓存找,找不到,有一个地址总线,就是路由cpu的和主存,同时去cpu和主存找,比较版本,去主存拿x,拿到x的值通过数据总线将值赋值cpu0的缓存

  • image

  • cpu0对x+1写,直接获取cpu0的x=0,进行加1(这里不会更新主存,也不会更新cpu1的缓存,cpu1缓存还没有x的值)

  • image

  • cpu1读x的值,首先在cpu1的缓存中找,找不到,根据地址总线,同时去cpu和主存找,比较版本(如果版本一样,会优先去主存的值),找到cpu0的x值,cpu0通过数据总线将数据优先更新cpu1的缓存x的值,在更新主存x的值

  • image

  • cpu1对x+1,直接获取cpu1的x=1,进行加1(这里会更新主存,也不会更新cpu0的缓存,但是会通过RFO通知其他cpu

  • image

其他情况可以自己去试一下。

通知协议:

Snoopy 协议。这种协议更像是一种数据通知的总线型的技术。CPU Cache通过这个协议可以识别其它Cache上的数据状态。如果有数据共享的话,可以通过广播机制将共享数据的状态通知给其它CPU Cache。这个协议要求每个CPU Cache 都可以“窥探”数据事件的通知并做出相应的反应。

MESI协议的状态:

Modified(已修改), Exclusive(独占的),Shared(共享的),Invalid(无效的)。

跟着动画走一遍,其实也不是很复杂。

了解这个对理解java中的volatile关键字其实是有帮助的!!

接下来的一篇文件就是典型用例啦!

真心感谢帅逼靓女们能看到这里,如果这个文章写得还不错,觉得有点东西的话

求点赞👍 求关注❤️ 求分享👥 对8块腹肌的我来说真的 非常有用!!!

如果本篇博客有任何错误,请批评指教,不胜感激 !❤️❤️❤️❤️