Cache: Fix the LRU policy for classic memory hierarchy
authorLena Olson <lena@cs.wisc.edu>
Fri, 29 Jun 2012 15:21:58 +0000 (11:21 -0400)
committerLena Olson <lena@cs.wisc.edu>
Fri, 29 Jun 2012 15:21:58 +0000 (11:21 -0400)
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.

src/mem/cache/tags/cacheset.cc
src/mem/cache/tags/cacheset.hh
src/mem/cache/tags/lru.cc

index dea1a6b457cbce1cdc2b7ed741833c92923fb203..8f96b947ac43757efece2eb0c077c2b198138ada 100644 (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);
+}
+
index a1cf937cf73f97b778315178f0a752242789b676..d38a1e927db1ac72391099a2f2cba78e6212a95d 100644 (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
index babcedc89b1c8ba8e54e13c36496d1cfc94fb2e2..c73f557b9dcef054bda0ab213a21ffda81ebf3ab 100644 (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);
     }
 }