blob: 86de56ee41a058065674b81b528b069d8a4a8802 [file] [log] [blame]
# HG changeset patch
# Parent 4ef5ff72f457bbe8c16d2377e2e6ba1409144463
Mem: Add a not most recently used (NMRU) replacement policy
diff --git a/src/mem/cache/base.cc b/src/mem/cache/base.cc
--- a/src/mem/cache/base.cc
+++ b/src/mem/cache/base.cc
@@ -45,14 +45,16 @@
* Definition of BaseCache functions.
*/
+#include "mem/cache/base.hh"
+
#include "debug/Cache.hh"
#include "debug/Drain.hh"
+#include "mem/cache/cache.hh"
+#include "mem/cache/mshr.hh"
#include "mem/cache/tags/fa_lru.hh"
#include "mem/cache/tags/lru.hh"
+#include "mem/cache/tags/nmru.hh"
#include "mem/cache/tags/random_repl.hh"
-#include "mem/cache/base.hh"
-#include "mem/cache/cache.hh"
-#include "mem/cache/mshr.hh"
#include "sim/full_system.hh"
using namespace std;
@@ -797,6 +799,8 @@
return new Cache<LRU>(this);
} else if (dynamic_cast<RandomRepl*>(tags)) {
return new Cache<RandomRepl>(this);
+ } else if (dynamic_cast<NMRU*>(tags)) {
+ return new Cache<NMRU>(this);
} else {
fatal("No suitable tags selected\n");
}
diff --git a/src/mem/cache/cache.cc b/src/mem/cache/cache.cc
--- a/src/mem/cache/cache.cc
+++ b/src/mem/cache/cache.cc
@@ -38,6 +38,7 @@
#include "mem/cache/tags/fa_lru.hh"
#include "mem/cache/tags/lru.hh"
+#include "mem/cache/tags/nmru.hh"
#include "mem/cache/tags/random_repl.hh"
#include "mem/cache/cache_impl.hh"
@@ -46,6 +47,7 @@
template class Cache<FALRU>;
template class Cache<LRU>;
+template class Cache<NMRU>;
template class Cache<RandomRepl>;
#endif //DOXYGEN_SHOULD_SKIP_THIS
diff --git a/src/mem/cache/tags/NMRU.py b/src/mem/cache/tags/NMRU.py
new file mode 100644
--- /dev/null
+++ b/src/mem/cache/tags/NMRU.py
@@ -0,0 +1,7 @@
+
+
+from Tags import BaseSetAssoc
+
+class NMRU(BaseSetAssoc):
+ type = 'NMRU'
+ cxx_header = "mem/cache/tags/nmru.hh"
\ No newline at end of file
diff --git a/src/mem/cache/tags/SConscript b/src/mem/cache/tags/SConscript
--- a/src/mem/cache/tags/SConscript
+++ b/src/mem/cache/tags/SConscript
@@ -31,9 +31,11 @@
Import('*')
SimObject('Tags.py')
+SimObject('NMRU.py')
Source('base.cc')
Source('base_set_assoc.cc')
Source('lru.cc')
+Source('nmru.cc')
Source('random_repl.cc')
Source('fa_lru.cc')
diff --git a/src/mem/cache/tags/nmru.cc b/src/mem/cache/tags/nmru.cc
new file mode 100644
--- /dev/null
+++ b/src/mem/cache/tags/nmru.cc
@@ -0,0 +1,79 @@
+
+
+/**
+ * @file
+ * Definitions of a NMRU tag store.
+ */
+
+#include "mem/cache/tags/nmru.hh"
+
+#include "base/random.hh"
+#include "debug/CacheRepl.hh"
+#include "mem/cache/base.hh"
+
+NMRU::NMRU(const Params *p)
+ : BaseSetAssoc(p)
+{
+}
+
+BaseSetAssoc::BlkType*
+NMRU::accessBlock(Addr addr, bool is_secure, Cycles &lat, int master_id)
+{
+ // Accesses are based on parent class, no need to do anything special
+ BlkType *blk = BaseSetAssoc::accessBlock(addr, is_secure, lat, master_id);
+
+ if (blk != NULL) {
+ // move this block to head of the MRU list
+ sets[blk->set].moveToHead(blk);
+ DPRINTF(CacheRepl, "set %x: moving blk %x (%s) to MRU\n",
+ blk->set, regenerateBlkAddr(blk->tag, blk->set),
+ is_secure ? "s" : "ns");
+ }
+
+ return blk;
+}
+
+BaseSetAssoc::BlkType*
+NMRU::findVictim(Addr addr) const
+{
+ BlkType *blk = BaseSetAssoc::findVictim(addr);
+
+ // if all blocks are valid, pick a replacement that is not MRU at random
+ if (blk->isValid()) {
+ // find a random index within the bounds of the set
+ int idx = random_mt.random<int>(1, assoc - 1);
+ assert(idx < assoc);
+ assert(idx >= 0);
+ blk = sets[extractSet(addr)].blks[idx];
+
+ DPRINTF(CacheRepl, "set %x: selecting blk %x for replacement\n",
+ blk->set, regenerateBlkAddr(blk->tag, blk->set));
+ }
+
+ return blk;
+}
+
+void
+NMRU::insertBlock(PacketPtr pkt, BlkType *blk)
+{
+ BaseSetAssoc::insertBlock(pkt, blk);
+
+ int set = extractSet(pkt->getAddr());
+ sets[set].moveToHead(blk);
+}
+
+void
+NMRU::invalidate(BlkType *blk)
+{
+ BaseSetAssoc::invalidate(blk);
+
+ // should be evicted before valid blocks
+ int set = blk->set;
+ sets[set].moveToTail(blk);
+}
+
+NMRU*
+NMRUParams::create()
+{
+ return new NMRU(this);
+}
diff --git a/src/mem/cache/tags/nmru.hh b/src/mem/cache/tags/nmru.hh
new file mode 100644
--- /dev/null
+++ b/src/mem/cache/tags/nmru.hh
@@ -0,0 +1,35 @@
+
+
+#ifndef __MEM_CACHE_TAGS_NMRU_HH__
+#define __MEM_CACHE_TAGS_NMRU_HH__
+
+#include "mem/cache/tags/base_set_assoc.hh"
+#include "params/NMRU.hh"
+
+class NMRU : public BaseSetAssoc
+{
+ public:
+ /** Convenience typedef. */
+ typedef NMRUParams Params;
+
+ /**
+ * Construct and initialize this tag store.
+ */
+ NMRU(const Params *p);
+
+ /**
+ * Destructor
+ */
+ ~NMRU() {}
+
+ /**
+ * Required functions for this subclass to implement
+ */
+ BlkType* accessBlock(Addr addr, bool is_secure, Cycles &lat,
+ int context_src);
+ BlkType* findVictim(Addr addr) const;
+ void insertBlock(PacketPtr pkt, BlkType *blk);
+ void invalidate(BlkType *blk);
+};
+
+#endif // __MEM_CACHE_TAGS_NMRU_HH__