mem: Support any number of master-IDs in stride prefetcher
authorStephan Diestelhorst <stephan.diestelhorst@arm.com>
Fri, 27 Mar 2015 08:56:03 +0000 (04:56 -0400)
committerStephan Diestelhorst <stephan.diestelhorst@arm.com>
Fri, 27 Mar 2015 08:56:03 +0000 (04:56 -0400)
The stride prefetcher had a hardcoded number of contexts (i.e. master-IDs)
that it could handle. Since master IDs need to be unique per system, and
every core, cache etc. requires a separate master port, a static limit on
these does not make much sense.

Instead, this patch adds a small hash map that will map all master IDs to
the right prefetch state and dynamically allocates new state for new master
IDs.

src/mem/cache/prefetch/stride.cc
src/mem/cache/prefetch/stride.hh

index 74c84b94ff2f9d36cacc17d864013e715c993d5c..bcd72f25aab67ca8921b18fc29bfce712bab8082 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013 ARM Limited
+ * Copyright (c) 2012-2013, 2015 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -59,27 +59,40 @@ StridePrefetcher::StridePrefetcher(const StridePrefetcherParams *p)
       pcTableAssoc(p->table_assoc),
       pcTableSets(p->table_sets),
       useMasterId(p->use_master_id),
-      degree(p->degree)
+      degree(p->degree),
+      pcTable(pcTableAssoc, pcTableSets, name())
 {
     // Don't consult stride prefetcher on instruction accesses
     onInst = false;
 
     assert(isPowerOf2(pcTableSets));
+}
 
-    for (int c = 0; c < maxContexts; c++) {
-        pcTable[c] = new StrideEntry*[pcTableSets];
-        for (int s = 0; s < pcTableSets; s++) {
-            pcTable[c][s] = new StrideEntry[pcTableAssoc];
-        }
+StridePrefetcher::StrideEntry**
+StridePrefetcher::PCTable::allocateNewContext(int context)
+{
+    auto res = entries.insert(std::make_pair(context,
+                              new StrideEntry*[pcTableSets]));
+    auto it = res.first;
+    chatty_assert(res.second, "Allocating an already created context\n");
+    assert(it->first == context);
+
+    DPRINTF(HWPrefetch, "Adding context %i with stride entries at %p\n",
+            context, it->second);
+
+    StrideEntry** entry = it->second;
+    for (int s = 0; s < pcTableSets; s++) {
+        entry[s] = new StrideEntry[pcTableAssoc];
     }
+    return entry;
 }
 
-StridePrefetcher::~StridePrefetcher()
-{
-    for (int c = 0; c < maxContexts; c++) {
+StridePrefetcher::PCTable::~PCTable() {
+    for (auto entry : entries) {
         for (int s = 0; s < pcTableSets; s++) {
-            delete[] pcTable[c][s];
+            delete[] entry.second[s];
         }
+        delete[] entry.second;
     }
 }
 
@@ -98,8 +111,6 @@ StridePrefetcher::calculatePrefetch(const PacketPtr &pkt,
     bool is_secure = pkt->isSecure();
     MasterID master_id = useMasterId ? pkt->req->masterId() : 0;
 
-    assert(master_id < maxContexts);
-
     // Lookup pc-based information
     StrideEntry *entry;
 
index 7d8f1211097cf9145f03e99ec6b7c13182110fa9..2798c823f5d82896b1485c4a06d749d34f53cc37 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013 ARM Limited
+ * Copyright (c) 2012-2013, 2015 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
 #ifndef __MEM_CACHE_PREFETCH_STRIDE_HH__
 #define __MEM_CACHE_PREFETCH_STRIDE_HH__
 
+#include "base/hashmap.hh"
 #include "mem/cache/prefetch/queued.hh"
 #include "params/StridePrefetcher.hh"
 
 class StridePrefetcher : public QueuedPrefetcher
 {
   protected:
-    static const int maxContexts = 64;
-
     const int maxConf;
     const int threshConf;
     const int minConf;
@@ -81,7 +80,30 @@ class StridePrefetcher : public QueuedPrefetcher
         int confidence;
     };
 
-    StrideEntry **pcTable[maxContexts];
+    class PCTable
+    {
+      public:
+        PCTable(int assoc, int sets, const std::string name) :
+            pcTableAssoc(assoc), pcTableSets(sets), _name(name) {}
+        StrideEntry** operator[] (int context) {
+            auto it = entries.find(context);
+            if (it != entries.end())
+                return it->second;
+
+            return allocateNewContext(context);
+        }
+
+        ~PCTable();
+      private:
+        const std::string name() {return _name; }
+        const int pcTableAssoc;
+        const int pcTableSets;
+        const std::string _name;
+        m5::hash_map<int, StrideEntry**> entries;
+
+        StrideEntry** allocateNewContext(int context);
+    };
+    PCTable pcTable;
 
     bool pcTableHit(Addr pc, bool is_secure, int master_id, StrideEntry* &entry);
     StrideEntry* pcTableVictim(Addr pc, int master_id);
@@ -90,7 +112,6 @@ class StridePrefetcher : public QueuedPrefetcher
   public:
 
     StridePrefetcher(const StridePrefetcherParams *p);
-    ~StridePrefetcher();
 
     void calculatePrefetch(const PacketPtr &pkt, std::vector<Addr> &addresses);
 };