mem: Add parameter to reserve MSHR entries for demand access
authorMitch Hayenga <mitch.hayenga@arm.com>
Tue, 23 Dec 2014 14:31:18 +0000 (09:31 -0500)
committerMitch Hayenga <mitch.hayenga@arm.com>
Tue, 23 Dec 2014 14:31:18 +0000 (09:31 -0500)
Adds a new parameter that reserves some number of MSHR entries for demand
accesses.  This helps prevent prefetchers from taking all MSHRs, forcing demand
requests from the CPU to stall.

src/mem/cache/BaseCache.py
src/mem/cache/base.cc
src/mem/cache/cache_impl.hh
src/mem/cache/mshr_queue.cc
src/mem/cache/mshr_queue.hh

index 9ffe399817e5e99e4ea822a7b5b9d6026f2ed8fa..035decf9a88e612cdbfd58c8126c869fb1d999fb 100644 (file)
@@ -54,6 +54,7 @@ class BaseCache(MemObject):
     max_miss_count = Param.Counter(0,
         "number of misses to handle before calling exit")
     mshrs = Param.Int("number of MSHRs (max outstanding requests)")
+    demand_mshr_reserve = Param.Int(1, "mshrs to reserve for demand access")
     size = Param.MemorySize("capacity in bytes")
     forward_snoops = Param.Bool(True,
         "forward snoops from mem side to cpu side")
index faa000c09f1ba24b33c47641e7bffa09138eaae3..d89517b9ce333165a8829e47cde7cdae84f3f0ec 100644 (file)
@@ -68,8 +68,8 @@ BaseCache::CacheSlavePort::CacheSlavePort(const std::string &_name,
 BaseCache::BaseCache(const Params *p)
     : MemObject(p),
       cpuSidePort(nullptr), memSidePort(nullptr),
-      mshrQueue("MSHRs", p->mshrs, 4, MSHRQueue_MSHRs),
-      writeBuffer("write buffer", p->write_buffers, p->mshrs+1000,
+      mshrQueue("MSHRs", p->mshrs, 4, p->demand_mshr_reserve, MSHRQueue_MSHRs),
+      writeBuffer("write buffer", p->write_buffers, p->mshrs+1000, 0,
                   MSHRQueue_WriteBuffer),
       blkSize(p->system->cacheLineSize()),
       hitLatency(p->hit_latency),
index f9eacb897d15166c5dd121dee5bafd8afd410117..da04cf6f95bb6eb5a6138fde144bed630a7d2e61 100644 (file)
@@ -1841,7 +1841,7 @@ Cache<TagStore>::getNextMSHR()
 
     // fall through... no pending requests.  Try a prefetch.
     assert(!miss_mshr && !write_mshr);
-    if (prefetcher && !mshrQueue.isFull()) {
+    if (prefetcher && mshrQueue.canPrefetch()) {
         // If we have a miss queue slot, we can try a prefetch
         PacketPtr pkt = prefetcher->getPacket();
         if (pkt) {
index 9146cddf73a654fb1eec8965aa0621592c59a365..cdd6da52cd39b39371b447aeaccbc2c68c56869f 100644 (file)
 using namespace std;
 
 MSHRQueue::MSHRQueue(const std::string &_label,
-                     int num_entries, int reserve, int _index)
+                     int num_entries, int reserve, int demand_reserve,
+                     int _index)
     : label(_label), numEntries(num_entries + reserve - 1),
-      numReserve(reserve), registers(numEntries),
-      drainManager(NULL), allocated(0), inServiceEntries(0), index(_index)
+      numReserve(reserve), demandReserve(demand_reserve),
+      registers(numEntries), drainManager(NULL), allocated(0),
+      inServiceEntries(0), index(_index)
 {
     for (int i = 0; i < numEntries; ++i) {
         registers[i].queue = this;
index 7ab3c7e742ad235eb8b74c647d3fe58827ce0233..7050421fe29045b1388176f76cd3fc29df170116 100644 (file)
@@ -77,6 +77,12 @@ class MSHRQueue : public Drainable
      */
     const int numReserve;
 
+    /**
+     * The number of entries to reserve for future demand accesses.
+     * Prevent prefetcher from taking all mshr entries
+     */
+    const int demandReserve;
+
     /**  MSHR storage. */
     std::vector<MSHR> registers;
     /** Holds pointers to all allocated entries. */
@@ -106,9 +112,11 @@ class MSHRQueue : public Drainable
      * @param num_entrys The number of entries in this queue.
      * @param reserve The minimum number of entries needed to satisfy
      * any access.
+     * @param demand_reserve The minimum number of entries needed to satisfy
+     * demand accesses.
      */
     MSHRQueue(const std::string &_label, int num_entries, int reserve,
-              int index);
+              int demand_reserve, int index);
 
     /**
      * Find the first MSHR that matches the provided address.
@@ -217,6 +225,15 @@ class MSHRQueue : public Drainable
         return (allocated > numEntries - numReserve);
     }
 
+    /**
+     * Returns true if sufficient mshrs for prefetch.
+     * @return True if sufficient mshrs for prefetch.
+     */
+    bool canPrefetch() const
+    {
+        return (allocated < numEntries - (numReserve + demandReserve));
+    }
+
     /**
      * Returns the MSHR at the head of the readyList.
      * @return The next request to service.