2012-03-15 68 views
0

我正在尋找在cache.c文件LRU代碼,但是這是唯一的代碼,我可以找到:SimpleScalar的緩存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算法。所以如果我錯過了一些東西,你能指點我的方向還是給我一些提示?

非常感謝。

+0

我瞭解情況:您正在閱讀某些代碼,其中一些代碼似乎已丟失。但我不明白這個問題是什麼。你爲什麼不問代碼的作者呢? – 2012-03-15 22:20:12

回答

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

很難說沒有看到代碼的其餘部分,但我看到兩個明顯的可能性在這裏。其中之一是,正如你所建議的那樣,LRU管理代碼缺失,可能是因爲編輯錯誤。

然而,我認爲可能性更大的可能性是,對於代碼的這個特定部分,LRU和FIFO管理做同樣的事情,所以它們取決於C開關的「通過」聲明在這種情況下爲兩者執行相同的代碼(但其他代碼可能會爲其他策略執行)。

+0

這更像是第二種情況,我應該檢查其餘的代碼。非常感謝你。 – astr627 2012-03-16 02:16:12

+0

有一個約定(我認爲很好)在空'case'標籤(本例中爲'LRU')之後放置'/ * fall-through * /'註釋。它使意圖清楚,即作者沒有忘記一個'break'聲明。 – gcbenison 2012-05-07 15:01:07

0

看起來代碼的其他部分按照FIFO或LRU順序排列cp->sets中的條目,使得無論替換策略如何,要替換的集合始終爲cp->sets[set].way_tail。這兩個替換策略僅在使用或添加行時有所不同,而不是在替換行時使用。