我碰巧在使用Simplescalar之前。实际上,Simplescalar已经实现了真正的LRU算法。
下面的注释清楚地描述了函数update_way_list。
/* insert BLK into the order way chain in SET at location WHERE */
static void
update_way_list(struct cache_set_t *set, /* set contained way chain */
struct cache_blk_t *blk, /* block to insert */
enum list_loc_t where) /* insert location */
你引用是从“高速缓存未命中”时,高速缓存被访问情况下,代码:
switch (cp->policy) {
case LRU:
case FIFO:
repl = cp->sets[set].way_tail;
update_way_list(&cp->sets[set], repl, Head);
break;
}
这里设定的最后的办法是选择为牺牲品,并且它被移到集合的头。 之后将被替换的块数据写回,然后将受害者替换为新的数据块。
区分LRU和FIFO最重要的部分来自于“高速缓存命中”的情况:
/* if LRU replacement and this is not the first element of list, reorder */
if (blk->way_prev && cp->policy == LRU)
{
/* move this block to head of the way (MRU) list */
update_way_list(&cp->sets[set], blk, Head);
}
因此,在一组的方式进行以下年龄的递减顺序:一组的头MRU(最近使用)块,而尾部是LRU。
这正是真正的LRU算法:当存在缓存命中时,将命中块升级为MRU方式,同时保留其他顺序。当存在高速缓存未命中时,选择LRU块作为牺牲品,并将新块置于MRU方式。如果我们删除先前的“缓存命中”代码,则不会记录访问历史记录,并且组中的方式遵循访问顺序,从而提供FIFO行为。如果我们删除行
update_way_list(&cp->sets[set], repl, Head);
在以前的“缓存未命中”的代码,那么新的模块将被放置在LRU方式,从而提供LIP(LRU插入策略)的行为。
我了解情况:您正在阅读某些代码,其中一些代码似乎已丢失。但我不明白这个问题是什么。你为什么不问代码的作者呢? – 2012-03-15 22:20:12