LRU算法,全称是 Least Recently Used(最近最少使用),是一种常见的缓存淘汰策略,广泛应用于操作系统的内存页面置换、数据库缓存、Web 缓存、CPU 缓存等场景。当前文章举例说明怎么使用verilog实现LRU算法。
1.生活场景类比
想象你有一个小书架,书架有 4 层(对应 4 路组相联缓存的 4 路),每层只能放一本书。你平时会从书架上拿书看,也会往书架上放新书。但是书架空间有限,当你要放一本新书,而书架已经满了的时候,你就得把一本最久没看的书拿下来,再把新书放上去,这就是 LRU 算法的核心思想。
2.代码逻辑
(1)记录看书顺序:LRU 位
为了知道哪本书是最久没看的,你在书架旁边放了一个小本子(对应代码里的 LRU 位),每次你从书架上拿书看或者放新书上去,就在小本子上记录一下。代码里用几个二进制位来记录每一路缓存行的使用情况,就像你在小本子上记录每一层书架的书的使用情况一样。
(2)选择要拿走的书:选择替换的缓存行
优先选空层:当你要放一本新书时,会先看看书架的 4 层里有没有空的。如果有,就直接把新书放在空的那一层。代码里也是一样,当要往缓存里加载新数据时,会先看看 4 路缓存行里有没有无效的(没被使用过的),如果有,就优先使用无效的那一路。
在这个例子中,set0_valid_r、set1_valid_r、set2_valid_r、set3_valid_r就像是判断每一层书架有没有书的标志。如果某一层没有书(无效),就选择这一层来放新书。
使用 LRU 算法:要是书架的 4 层都有书(4 路缓存行都有效),你就得看看小本子上的记录,找出最久没看的那本书,把它拿下来。代码里根据 LRU 位的值来确定哪一路是最近最少使用的。
这里的set_lru_bits_r就像是小本子上的记录,通过判断它的值,就能知道哪一层的书是最久没看的。
(3) 更新小本子记录:更新 LRU 位
每当你从书架上拿一本书看或者放一本新书上去,都要在小本子上更新一下记录,表明这本书是最近看的。代码里也是,每当有数据写入某一路缓存行时,就表示这一路是最近使用的,要更新 LRU 位来反映这个情况。
write_set0、write_set1、write_set2等就像是你从某一层拿书或者放书的操作,根据不同的操作,更新小本子(LRU 位)上的记录。
(4)保存新记录:保存更新后的 LRU 位
更新完小本子上的记录后,要保证下次看的时候还是最新的记录。代码里也是,更新完 LRU 位后,要把新的 LRU 位存回标签 RAM,这样下次选择要拿走的书(替换的缓存行)时就能使用最新的使用情况信息。
这里就是把更新后的 LRU 位(nxt_lru_bits)存到标签 RAM 里。
通过这个生活中的例子,你应该能更直观地理解和实现LRU 算法了。