Реализация симплескалярного кэша LRU - PullRequest
0 голосов
/ 16 марта 2012

Я ищу код LRU в файле cache.c, но это единственный код, который я могу найти:

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 ]

2 голосов
/ 16 марта 2012

Трудно сказать, не видя остальной код, но я вижу здесь две очевидные возможности.Один из них заключается в том, что, как вы предполагаете, код для управления LRU отсутствует, возможно, из-за какой-то ошибки в редактировании.

Вероятность, которую я считаю более вероятной, однако, будет для этого конкретногоВ части кода управление LRU и FIFO делает одно и то же, поэтому они зависят от «провала» оператора C switch, чтобы в этом случае был выполнен один и тот же код (но, предположительно, другой код будет выполнен длядругие политики).

1 голос
/ 12 мая 2013

Мне случалось использовать 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 Insertion Policy).

0 голосов
/ 16 марта 2012

Похоже, что другие разделы кода упорядочивают записи в cp->sets в порядке FIFO или LRU, так что заменяемый набор всегда равен cp->sets[set].way_tail независимо от политики замены.Две политики замены отличаются только при использовании или добавлении строки, а не при замене строки.

...