25

3.5.4 Cache中主存块的替换算法
​ 全相联映射和组相联映射需要,直接相连映射不需要。从主存向Cache传送一个新块,当Cache或Cache组中的空间已被占满时,就需要使用替换算法置换Cache行。而

随机算法(RAND)

算法:若Cache已满,则随机选择一块替换。

特点:实现简单,但完全没考虑局部性原理,命中率低,(实际效果很不稳定)

先进先出算法(FIFO)

算法:若Cache已满,则替换最先被调入Cache的块

特点:FIFO依然没考虑局部性原理,最先被调入Cache的块也有可能是被频繁访问的

近期最少使用(LRU)

算法:为每一个Cache块设置一个“计数器”,用于记录每个Cache块已经有多久没被访问了。当Cache满后替换“计数器”最大的

①命中时,所命中的行的计数器清零,比其低的计数器加1,其余不变;
②未命中且还有空闲行时,新装入的行的计数器置0,其余非空闲行全加1;
③未命中且无空闲行时,计数值最大的行的信息块被淘汰,新装行的块的计数器置0,其余全加1。
Cache块的总数=2n,则计数器只需n位。且Cache装满后所有计数器的值定不重复

特点:基于“局部性原理”,近期被访问过的主存块,在不久的将来也很有可能被再次访问,因此淘汰最久没被访问过的块是合理的。LRU算法的实际运行效果优秀,Cache命中率高。

若被频繁访问的主存块数量>Cache行的数量,则有可能发生“抖动”,如:[1,2,3,4,5,1,2,3,4,5,1,2…)

​ 假定采用四路组相联映射,有5个主存块{1,2,3,4,5}映射到Cache的同一组,对于主存访问{1,2,3,4,1,2,5,1,2,3,4,5},采用LRU算法的替换过程如图。

 

最近不经常使用(LFU)

算法:为每一个Cache块设置一个“计数器”,用于记录每个Cache块被访问过几次。当Cache满后替换“计数器”最小的。

新调入的块计数器=0,之后每被访问一次计数器+1。需要替换时,选择计数器最小的一行

若有多个计数器最小的行,可按行号递增或FIFO策略进行选择

特点:曾经被经常访问的主存块在未来不一定会用到(如:微信视频聊天相关的块),并没有很好地遵循局部性原理,因此实际运行效果不如LRU

3.5.5 Cache写策略
​ 因为Cache中的内容是主存块副本,当对Cache中的内容进行更新时,就需选用写操作策略使Cache内容和主存内容保持一致。此时分两种情况。

写命中

写回法:当CPU对Cache写命中时,只修改Cache的内容,而不立即写入主存,只有当此块被换出时才写回主存
减少了访存次数,但存在数据不一致的隐患。

每个Cache行必须设直一个标志位(脏位),以反映此块是否被CPU修改过。

全写法:当CPU对Cache写命中时,必须把数据同时写入Cache和主存,一般使用写缓冲(write buffer)

访存次数增加,速度变慢,但更能保证数据一致性


写不命中

写分配法:当CPU对Cache写不命中时,把主存中的块调入Cache,在Cache中修改。
通常搭配写回法使用。
非写分配法:当CPU对Cache写不命中时,只写入主存,不调入Cache。
搭配全写法使用。
只有“读”未命中时才调入Cache
多级Cache

现代计算机常采用多级Cache离CPU越近的速度越快,容量越小离CPU越远的速度越慢,容量越大。

 

各级Cache之间常采用**“全写法+非写分配法”**

Cache-主存 之间常采用**“写回法+写分配法”**

posted @ 2025-02-15 19:43  cor0000  阅读(27)  评论(0)    收藏  举报