summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLena Olson <lena@cs.wisc.edu>2012-06-29 11:21:58 -0400
committerLena Olson <lena@cs.wisc.edu>2012-06-29 11:21:58 -0400
commitd2ebade5a5f5a20a159f62b9e76c6abdf8b00726 (patch)
tree5d8f67778c6e27970b5f31bd7fbcc7b1a8038513 /src
parentfcccab0dcdc57fe838bb64d584ebbcf28c059dee (diff)
downloadgem5-d2ebade5a5f5a20a159f62b9e76c6abdf8b00726.tar.xz
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.
Diffstat (limited to 'src')
-rw-r--r--src/mem/cache/tags/cacheset.cc24
-rw-r--r--src/mem/cache/tags/cacheset.hh6
-rw-r--r--src/mem/cache/tags/lru.cc4
3 files changed, 34 insertions, 0 deletions
diff --git a/src/mem/cache/tags/cacheset.cc b/src/mem/cache/tags/cacheset.cc
index dea1a6b45..8f96b947a 100644
--- a/src/mem/cache/tags/cacheset.cc
+++ b/src/mem/cache/tags/cacheset.cc
@@ -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);
+}
+
diff --git a/src/mem/cache/tags/cacheset.hh b/src/mem/cache/tags/cacheset.hh
index a1cf937cf..d38a1e927 100644
--- a/src/mem/cache/tags/cacheset.hh
+++ b/src/mem/cache/tags/cacheset.hh
@@ -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
diff --git a/src/mem/cache/tags/lru.cc b/src/mem/cache/tags/lru.cc
index babcedc89..c73f557b9 100644
--- a/src/mem/cache/tags/lru.cc
+++ b/src/mem/cache/tags/lru.cc
@@ -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);
}
}