Cache: Fix the LRU policy for classic memory hierarchy

The LRU policy always evicted the least recently touched way, even if it
contained valid data and another way was invalid, as can happen if a block has
been invalidated by coherance.  This can result in caches never warming up even
though they are replacing blocks.  This modifies the LRU policy to move blocks
to LRU position on invalidation.
This commit is contained in:
Lena Olson 2012-06-29 11:21:58 -04:00
parent fcccab0dcd
commit d2ebade5a5
3 changed files with 34 additions and 0 deletions

View file

@ -66,3 +66,27 @@ CacheSet::moveToHead(CacheBlk *blk)
} while (next != blk);
}
void
CacheSet::moveToTail(CacheBlk *blk)
{
// nothing to do if blk is already tail
if (blks[assoc-1] == blk)
return;
// write 'next' block into blks[i], moving from LRU to MRU
// until we overwrite the block we moved to tail.
// start by setting up to write 'blk' into tail
int i = assoc - 1;
CacheBlk *next = blk;
do {
assert(i >= 0);
// swap blks[i] and next
CacheBlk *tmp = blks[i];
blks[i] = next;
next = tmp;
--i;
} while (next != blk);
}

View file

@ -66,6 +66,12 @@ class CacheSet
*/
void moveToHead(CacheBlk *blk);
/**
* Move the given block to the tail of the list.
* @param blk The block to move
*/
void moveToTail(CacheBlk *blk);
};
#endif

View file

@ -213,6 +213,10 @@ LRU::invalidateBlk(BlkType *blk)
blk->status = 0;
blk->isTouched = false;
blk->clearLoadLocks();
// should be evicted before valid blocks
unsigned set = blk->set;
sets[set].moveToTail(blk);
}
}