这个时候可以再回头看看"图4:一个存储器层次结构的示例" 。
下面这张图和这段文字来自《深入理解计算机系统》(CSAPP),大家可以有个更严谨和细节的认识 。
文章插图
图8:存储器层次结构中基本的缓存原理
存储器层次结构的中心思想:位于k层的更快更小的存储设备作为位于k+1层得更大更慢的存储设备的缓存;数据总是以块大小为传送单元(transfer unit)在第k层和第k+1层之间来回拷贝的;任何一对相邻的层次之间传送的块大小是固定的,即每一级缓存的块大小是固定的 。但是其它的层次对之间可以有不同的块大小 。
当程序需要第k+1层的某个数据对象d时,它首先在当前存储在第k层的一个块中查找d 。如果d刚好在k层,那么就是缓存命中 。如果第k层中没有缓存数据对象d,那么就是缓存命不中 。当缓存不命中发生时,第k层的缓存从第k+1层 缓存中取出包含d的那个块,如果第k层的缓存已经满了的话,可能会覆盖现存的一个块 。(覆盖策略可以使用常见的LRU算法) 。
volatile 关键字在java和C当中,有一个volatile关键字(其他语言估计也有),它的作用就是在多线程时保证变量的内存可见性,但是具体怎么理解呢?
我们在"图4:一个存储器层次结构的示例"中,说的缓存结构其实对于一个单核CPU而言的,比如 对于 一个四核三级缓存的CPU,它的缓存结构是这样的 。
文章插图
图9:多核处理器缓存结构
我们可以看到L3是四个核共有的,但是L2,L1其实是每个核私有的,如果我有一个变量var,它会被两个线程同时读取,这两个线程在两个核上并行执行,因为我们的缓存原理,这个var可能分别在两个核的 L2或L1缓存,这样读取速度最快,但是该var值可能就分别被这两个核分别修改成不同的值,最后将值回写到L3或L4主存,此时就会发生bug了 。
所以volatile关键字就是预防这种情况,对于被volatile修饰的的变量,每次CPU需要读取时,都至少要从L3读取,并且CPU计算结束后,也立刻回写到L3中,这样读写速度虽然减慢了一些,但是避免了该值在每个core的私有缓存中单独操作而其他核不知道 。
推荐阅读
- 华为手机应用怎么移到sd卡 华为手机应用移到sd卡的方法是什么
- 9月3日是什么日子 9月3日是哪个节日
- 荣耀9x是什么屏幕荣耀9x什么屏幕
- 三红蜜柚是哪里产的 三红蜜柚是什么地方的
- 12星座女和渣男谈恋爱是什么体验?
- 最大数字是什么单位 数字办公室是什么单位
- 桂林山水甲天下的下一句是什么谚语 桂林山水甲天下的下一句是什么?
- 福特是什么旗下的
- 怎样清洗泡菜坛子 清洗坛子的步骤是什么
- 奔驰abs和防滑灯亮是什么原因?