mem-cache: Make PCTable context independent
authorDaniel <odanrc@yahoo.com.br>
Sun, 11 Nov 2018 15:11:40 +0000 (16:11 +0100)
committerDaniel Carvalho <odanrc@yahoo.com.br>
Thu, 15 Nov 2018 16:53:07 +0000 (16:53 +0000)
Move the unordered_map outside of the PCTable, as it
belongs to the StridePrefetcher. By doing so we are
moving towards a table that ressembles the ones of
the Tags classes.

Some functions have been moved from the prefetcher to
the PCTable, as they didn't belong there. As such, they
have been renamed to remove the unnecessary prefix.

Change-Id: I3e54bc7dee65e1f78d96b0d548ac8345b7bd4364
Signed-off-by: Daniel <odanrc@yahoo.com.br>
Reviewed-on: https://gem5-review.googlesource.com/c/14358
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Maintainer: Nikos Nikoleris <nikos.nikoleris@arm.com>

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

index fde4f30117053127c30b47ff5f4789f66fe3bf1e..c09facef015c424351e16f53c6c88e60fea86d5b 100644 (file)
@@ -66,28 +66,42 @@ StridePrefetcher::StridePrefetcher(const StridePrefetcherParams *p)
       pcTableAssoc(p->table_assoc),
       pcTableSets(p->table_sets),
       useMasterId(p->use_master_id),
-      degree(p->degree),
-      pcTable(pcTableAssoc, pcTableSets, name())
+      degree(p->degree)
 {
     assert(isPowerOf2(pcTableSets));
 }
 
-std::vector<std::vector<StridePrefetcher::StrideEntry>>&
-StridePrefetcher::PCTable::allocateNewContext(int context)
+StridePrefetcher::PCTable*
+StridePrefetcher::findTable(int context)
 {
-    auto res = entries.insert(std::make_pair(context,
-        std::vector<std::vector<StrideEntry>>(pcTableSets)));
-    auto it = res.first;
-    chatty_assert(res.second, "Allocating an already created context\n");
-    assert(it->first == context);
+    // Check if table for given context exists
+    auto it = pcTables.find(context);
+    if (it != pcTables.end())
+        return &it->second;
+
+    // If table does not exist yet, create one
+    return allocateNewContext(context);
+}
+
+StridePrefetcher::PCTable*
+StridePrefetcher::allocateNewContext(int context)
+{
+    // Create new table
+    auto insertion_result = pcTables.insert(std::make_pair(context,
+        PCTable(pcTableAssoc, pcTableSets, name())));
 
     DPRINTF(HWPrefetch, "Adding context %i with stride entries\n", context);
 
-    std::vector<std::vector<StrideEntry>>& table = it->second;
-    for (auto& set : table) {
+    // Get iterator to new pc table, and then return a pointer to the new table
+    return &(insertion_result.first->second);
+}
+
+StridePrefetcher::PCTable::PCTable(int assoc, int sets, const std::string name)
+    : pcTableAssoc(assoc), pcTableSets(sets), _name(name), entries(pcTableSets)
+{
+    for (auto& set : entries) {
         set.resize(pcTableAssoc);
     }
-    return table;
 }
 
 StridePrefetcher::PCTable::~PCTable()
@@ -109,8 +123,11 @@ StridePrefetcher::calculatePrefetch(const PacketPtr &pkt,
     bool is_secure = pkt->isSecure();
     MasterID master_id = useMasterId ? pkt->req->masterId() : 0;
 
+    // Get corresponding pc table
+    PCTable* pcTable = findTable(master_id);
+
     // Search for entry in the pc table
-    StrideEntry *entry = findEntry(pc, is_secure, master_id);
+    StrideEntry *entry = pcTable->findEntry(pc, is_secure);
 
     if (entry != nullptr) {
         // Hit in table
@@ -164,7 +181,7 @@ StridePrefetcher::calculatePrefetch(const PacketPtr &pkt,
         DPRINTF(HWPrefetch, "Miss: PC %x pkt_addr %x (%s)\n", pc, pkt_addr,
                 is_secure ? "s" : "ns");
 
-        StrideEntry* entry = pcTableVictim(pc, master_id);
+        StrideEntry* entry = pcTable->findVictim(pc);
         entry->instAddr = pc;
         entry->lastAddr = pkt_addr;
         entry->isSecure= is_secure;
@@ -174,7 +191,7 @@ StridePrefetcher::calculatePrefetch(const PacketPtr &pkt,
 }
 
 inline Addr
-StridePrefetcher::pcHash(Addr pc) const
+StridePrefetcher::PCTable::pcHash(Addr pc) const
 {
     Addr hash1 = pc >> 1;
     Addr hash2 = hash1 >> floorLog2(pcTableSets);
@@ -182,21 +199,21 @@ StridePrefetcher::pcHash(Addr pc) const
 }
 
 inline StridePrefetcher::StrideEntry*
-StridePrefetcher::pcTableVictim(Addr pc, int master_id)
+StridePrefetcher::PCTable::findVictim(Addr pc)
 {
     // Rand replacement for now
     int set = pcHash(pc);
     int way = random_mt.random<int>(0, pcTableAssoc - 1);
 
     DPRINTF(HWPrefetch, "Victimizing lookup table[%d][%d].\n", set, way);
-    return &pcTable[master_id][set][way];
+    return &entries[set][way];
 }
 
 inline StridePrefetcher::StrideEntry*
-StridePrefetcher::findEntry(Addr pc, bool is_secure, int master_id)
+StridePrefetcher::PCTable::findEntry(Addr pc, bool is_secure)
 {
     int set = pcHash(pc);
-    std::vector<StrideEntry>& set_entries = pcTable[master_id][set];
+    std::vector<StrideEntry>& set_entries = entries[set];
     for (int way = 0; way < pcTableAssoc; way++) {
         StrideEntry* entry = &set_entries[way];
         // Search ways for match
index da3bbb33f92556866cf86162ba1e4ac88f050d8d..ec22ca63f9b1a5cbf83566dffa3f7d339c43537a 100644 (file)
@@ -89,44 +89,72 @@ class StridePrefetcher : public QueuedPrefetcher
     class PCTable
     {
       public:
-        PCTable(int assoc, int sets, const std::string name) :
-            pcTableAssoc(assoc), pcTableSets(sets), _name(name) {}
-
-        std::vector<std::vector<StrideEntry>>& operator[] (int context) {
-            auto it = entries.find(context);
-            if (it != entries.end())
-                return it->second;
+        /**
+         * Default constructor. Create a table with given parameters.
+         *
+         * @param assoc Associativity of the table.
+         * @param sets Number of sets in the table.
+         * @param name Name of the prefetcher.
+         */
+        PCTable(int assoc, int sets, const std::string name);
+
+        /**
+         * Default destructor.
+         */
+        ~PCTable();
 
-            return allocateNewContext(context);
-        }
+        /**
+         * Search for an entry in the pc table.
+         *
+         * @param pc The PC to look for.
+         * @param is_secure True if the target memory space is secure.
+         * @return Pointer to the entry.
+         */
+        StrideEntry* findEntry(Addr pc, bool is_secure);
+
+        /**
+         * Find a replacement victim to make room for given PC.
+         *
+         * @param pc The PC value.
+         * @return The victimized entry.
+         */
+        StrideEntry* findVictim(Addr pc);
 
-        ~PCTable();
       private:
         const std::string name() {return _name; }
         const int pcTableAssoc;
         const int pcTableSets;
         const std::string _name;
-        std::unordered_map<int, std::vector<std::vector<StrideEntry>>> entries;
-
-        std::vector<std::vector<StrideEntry>>& allocateNewContext(int context);
+        std::vector<std::vector<StrideEntry>> entries;
+
+        /**
+         * PC hashing function to index sets in the table.
+         *
+         * @param pc The PC value.
+         * @return The set to which this PC maps.
+         */
+        Addr pcHash(Addr pc) const;
     };
-    PCTable pcTable;
+    std::unordered_map<int, PCTable> pcTables;
 
     /**
-     * Search for an entry in the pc table.
+     * Try to find a table of entries for the given context. If none is
+     * found, a new table is created.
      *
-     * @param pc The PC to look for.
-     * @param is_secure True if the target memory space is secure.
-     * @param master_id The context.
-     * @return Pointer to the entry.
+     * @param context The context to be searched for.
+     * @return The table corresponding to the given context.
      */
-    StrideEntry* findEntry(Addr pc, bool is_secure, int master_id);
+    PCTable* findTable(int context);
 
-    StrideEntry* pcTableVictim(Addr pc, int master_id);
+    /**
+     * Create a PC table for the given context.
+     *
+     * @param context The context of the new PC table.
+     * @return The new PC table
+     */
+    PCTable* allocateNewContext(int context);
 
-    Addr pcHash(Addr pc) const;
   public:
-
     StridePrefetcher(const StridePrefetcherParams *p);
 
     void calculatePrefetch(const PacketPtr &pkt,