Cache很小,主存很大。如果Cache满了怎么办?——替换算法
直接映射
对于直接映射,我们只能放到特定位置。如果这个位置原来已经有数据了,只需要把原来的数据替换掉,所以采用直接映射方式不需要考虑替换算法到底要替换那一块的问题,因为只能放到固定的位置
所以Cache主存块替换算法只会被运用到全相联和组相联映射
Cache的四种替换算法:
随机算法(全相联映射)
Cache块满了的话,随机选择一块替换
CPU进行访存时,若未命中,则先访问对应的主存块,并把信息调入/复制到对应的Cache块中。(每访问一个主存块就一定需要把这主存块立即调入Cache)
因为初始状态Cache内是空的,所以一开始依次访问Cache的时候都是未命中,也就是一开始都是先访问的主存块,然后再把信息调入到Cache块中
由于依次访问1234时都没装满,所以不需要Cache替换。
接下来再访问125,访问1,2时都会命中,因为此时对应的Cache 块内已经有信息了,而访问5时,由于Cache块中存储的信息满了且没有对应的信息也就无法命中,所以要进行Cache的替换。根据随机算法的规则,可以随机的选择替换任意个Cache块
接下来访问1,2都可以命中,而访问3时由于已经被5覆盖,而Cache也满了,且没有对应的信息也就是无法命中,此时要进行Cache替换,随机选择一个Cache块进行替换
接下来访问4也是一样的道理,而访问5时就可以命中了
所以随机算法完全替换策略完全是随机的,完全没有考虑局部性原理
先进先出算法(全相联映射)
若Cache已满,则替换最先被调入到Cache的块
当访问5的时候会出现未命中且Cache已满的情况,此时需要进行Cache的替换。按照先进先出算法的替换规则,1是最先调入到Cache块中的,所以替换1号
访问1,2,3同理
访问4号主存块的时候,此时最先被调入的就是5了
抖动现象:频繁地换入换出
近期最少使用算法(LRU)
为每一个Cache块/行设置一个计数器,用于记录这个Cache块里面存放的主存块已经多久没有被访问过了,当Cache满后替换“计数器”最大的(计数器最大就代表着是最久没被访问过的)
做题的时候可以采取的手算方法:当需要替换一个Cache块的时候,从当前访问的这个主存块号这个位置开始往前看,看那些主存块是最近被访问过的
比如访问5的时候,从5这个位置往前看,2最近被访问过,1最近被访问过,4最近被访问过,所以此时Cache里面最久没有被访问过的是3号块d,所以这个时候替换3,而其它不变
在机器内部是如何实现这个算法的
每个Cache需要有个标记需要记录Cache行所存储的主存块号,还需要增加一个有效位。而LRU算法还必须 给每个Cache添加一个计数器。刚开始Cache行都为空,则计数器也都为空
计数器的变化规则:
①可以保证最近访问过的主存块其计数器值最小,可以恢复成0,然后越久没有被访问过的Cache行其计数器不断+1
也可以让大的值+1变成4但是把3变4没意义,保留原本的3也可以达到同样的效果,因为设置计数器的目的就是想通过值的大小来判断应该替换那个主存块,3本来已经是最大的了,再让其加一,没有意义。这样处理的好处是,四个计数器的值肯定是0123,数字是连续的
可以保证所有计数器的值只有可能出现0123,这意味着当Cache块的总数只有2^n 块时,只需要n个比特位来作为计数器即可。
例如上面这个例子中,4个Cache块只需要2bit信息来表示计数器即可,2bit刚好可以表示0123这几种数字
考虑到局部性原理——根据时间局部性,近期访问过的主存块在不久的将来也很有可能再次访问。
抖动现象
若频繁访问到的主存块的数量 > Cache行中的数量,有可能发生抖动现象,比如按12345,12345来访问主存块,此时被频繁访问到的主存有5块而Cache行的数量只有4
最不经常使用算法(LFU)