Simplescalar缓存LRU实现

时间:2012-03-15 22:06:15

标签: c caching lru

我正在寻找cache.c文件中的LRU代码,但这是我能找到的唯一代码:

switch (cp->policy) {

  case LRU:

  case FIFO:

    repl = cp->sets[set].way_tail;
    update_way_list(&cp->sets[set], repl, Head);
    break;

看起来我错过了LRU代码,我认为应该在冒号之后放置LRU算法。所以如果我错过了什么,你能指出我正确的方向还是给我一些提示?

非常感谢。

3 个答案:

答案 0 :(得分:2)

很难说没有看到其余的代码,但我在这里看到两个明显的可能性。一个是,正如你所建议的那样,LRU管理的代码丢失了,可能是因为编辑中的错误。

然而,我认为更有可能的可能性是,对于代码的这个特定部分,LRU和FIFO管理做同样的事情,所以它们取决于C switch语句的“堕落”在这种情况下为两者执行相同的代码(但可能会为其他策略执行其他代码)。

答案 1 :(得分:1)

我之前碰巧使用过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插入策略)行为。

答案 2 :(得分:0)

看起来代码的其他部分按照FIFO或LRU顺序排列cp->sets中的条目,使得无论替换策略是什么,要替换的集合始终为cp->sets[set].way_tail。两个替换策略仅在使用或添加行时不同,而不是在替换行时。