Cache基本原理、基本概念
Cache工作原理
局部性原理
空间局部性:在最近的未来要用到的信息(指令和数据),很可能与现在正在使用的信息在存储空间上是邻近的 (数组元素、顺序执行的指令代码)
时间局部性:在最近的未来要用到的信息,很可能是现在正在使用的信息 (循环结构的指令代码)基于局部性原理,不难想到,可以把CPU目前访问的地址“周围”的部分数据放到Cache中
程序B按“列优先”访问二维数组,空间局部性更差
性能分析
如何区分Cache与主存的数据块对应关系?
Cache和主存的映射方式
Cache很小,主存很大。如果Cache满了怎么办?
替换算法
CPU修改了Cache中的数据副本,如何确保主存中数据母本的一致性?
Cache写策略
Cache和主存的映射方式
全相联映射
主存块可以放在Cache的任意位置
(b)直接映射
每个主存块只能放到一个特定的位置
Cache块号=主存块号% Cache总块数
©组相联映射
Cache块分为若干组,每个主存块可放到特定分组中的任意一个位置
组号=主存块号%分组数
全相联映射(随意放)
假设某个计算机的主存地址空间大小为256MB,按字节编
址,其数据Cache有8个Cache行,行长为64B。
Cache行:即Cache块,与主存块的大小相等
实现映射
直接映射(只能放固定位置)
假设某个计算机的主存地址空间大小为256MB,按字节编
址,其数据Cache有8个Cache行,行长为64B。
直接映射,主存块在Cache中的位置=主存块号%Cache总块数
组相联映射(可放到特定分组)
假设某个计算机的主存地址空间大小为256MB,按字节编
址,其数据Cache有8个Cache行,行长为64B。
组相联映射,所属分组=主存块号%分组数
Cache替换算法
随机算法(RAND)
随机算法(RAND,Random)――若Cache已满,则随机选择一块替换。
设总共有4个cache块,初始整个Cache为空。采用全相联映射,依次访问主存块{1,2,3,4,1,2,5,1,2,3,4,5}
随机算法――实现简单,但完全没考虑局部性原理,命中率低,实际效果很不稳定
先进先出算法(FIFO)
先进先出算法(FIFO,First In First Out)—-若Cache已满,则替换最先被调入Cache的块
设总共有4个Cache块,初始整个Cache为空。采用全相联映射,依次访问主存块 {1,2,3,4,1,2,5,1,2,3,4, 5}
先进先出算法――实现简单,最开始按#O#1#2#3放入Cache,之后轮流替换#O#1#2#3
FIFO依然没考虑局部性原理,最先被调入Cache的块也有可能是被频繁访问的
抖动现象:频繁的换入换出现象(刚被替换的块很快又被调入)
近期最少使用算法(LRU)
近期最少使用算法(LRU, Least RecentlyUsed )–为每一个Cache块设置一个“计数器”,用于记录每个Cache块已经有多久没被访问了。当Cache满后替换“计数器”最大的
设总共有4个Cache块,初始整个Cache为空。采用全相联映射,依次访问主存块{1,2,3,4,1,2,5,1,2,3,4,5}
①命中时,所命中的行的计数器清零,比其低的计数器加1,其余不变;
②未命中且还有空闲行时,新装入的行的计数器置0,其余非空闲行全加1;
③未命中且无空闲行时,计数值最大的行的信息块被淘汰,新装行的块的计数器置0,其余全加1。
LRU算法――基于“局部性原理”,近期被访问过的主存块,在不久的将来也很有可能被再次访问,因此淘汰最久没被访问过的块是合理的。LRU算法的实际运行效果优秀,Cache命中率高。
若被频繁访问的主存块数量>Cache行的数量,则有可能发生“抖动”,如:1,2,3,4,5,1,2,3,4,5,1,…]
最不经常使用算法(LFU)
最不经常使用算法(LFU, Least Frequently Used )—-为每一个Cache块设置一个“计数器”,用于记录每个cache块被访问过几次。当Cache满后替换“计数器”最小的
设总共有4个Cache块,初始整个Cache为空。采用全相联映射,依次访问主存块{1,2,3,4,1,2,5,1,2,3,4,5}
新调入的块计数器=O,之后每被访问一次计数器+1。需要替换时,选择计数器最小的一行
LFU算法―一曾经被经常访问的主存块在未来不一定会用到(如:微信视频聊天相关的块),并没有很好地遵循局部性原理,因此实际运行效果不如LRU
Cache写策略
写命中
写回法(write-back)——当CPU对Cache写命中时,只修改Cache的内容,而不立即写入主存,只有当此块被换出时才写回主存
减少了访存次数,但存在数据不一致的隐患。
全写法(写直通法,write-through)——当CPU对Cache写命中时,必须把数据同时写入cache和主存,一般使用写缓冲(write buffer)
访存次数增加,速度变慢,但更能保证数据一致性
使用写缓冲,CPU写的速度很快,若写操作不频繁,则效果很好。若写操作很频繁,可能会因为写缓冲饱和而发生阻塞
写不命中
写分配法(write-allocate)——当CPU对Cache写不命中时,把主存中的块调入Cache,在Cache中修改。通常搭配写回法使用。
写回法(write-back)——当CPU对Cache写命中时,只修改Cache的内容,而不立即写入主存,只有当此块被换出时才写回主存
只有“读”未命中时才调入Cache
非写分配法(not-write-allocate)——当CPU对Cache写不命中时只写入主存,不调入Cache。搭配全写法使用。
全写法(写直通法,write-through)——当CPU对Cache写命中时,必须把数据同时写入Cache和主存,一般使用写缓冲(write buffer)
多级Cache
现代计算机常采用多级Cache
离CPU越近的速度越快,容量越小
离CPU越远的速度越慢,容量越大