Daniel Carvalho has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/24603 )

Change subject: mem-cache: Use AssociativeSet in Stride prefetcher
......................................................................

mem-cache: Use AssociativeSet in Stride prefetcher

Avoid replicating associative set functionality in Stride prefetcher's
pc tables.

The indexing policy used previously had some peculiarities, so both
the extractTag and extractSet have been made virtual so that previous
behavior could be kept.

Change-Id: I19a86cb3c4b40031fef427d5f7eed9d5c5673a44
Signed-off-by: Daniel R. Carvalho <oda...@yahoo.com.br>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/24603
Reviewed-by: Nikos Nikoleris <nikos.nikole...@arm.com>
Maintainer: Nikos Nikoleris <nikos.nikole...@arm.com>
Tested-by: kokoro <noreply+kok...@google.com>
---
M src/mem/cache/prefetch/Prefetcher.py
M src/mem/cache/prefetch/stride.cc
M src/mem/cache/prefetch/stride.hh
M src/mem/cache/tags/indexing_policies/base.hh
M src/mem/cache/tags/indexing_policies/set_associative.hh
5 files changed, 86 insertions(+), 152 deletions(-)

Approvals:
  Nikos Nikoleris: Looks good to me, approved; Looks good to me, approved
  kokoro: Regressions pass



diff --git a/src/mem/cache/prefetch/Prefetcher.py b/src/mem/cache/prefetch/Prefetcher.py
index 51132f9..f131ccf 100644
--- a/src/mem/cache/prefetch/Prefetcher.py
+++ b/src/mem/cache/prefetch/Prefetcher.py
@@ -139,6 +139,11 @@
throttle_control_percentage = Param.Percent(0, "Percentage of requests \ that can be throttled depending on the accuracy of the prefetcher.")

+class StridePrefetcherHashedSetAssociative(SetAssociative):
+    type = 'StridePrefetcherHashedSetAssociative'
+    cxx_class = 'Prefetcher::StridePrefetcherHashedSetAssociative'
+    cxx_header = "mem/cache/prefetch/stride.hh"
+
 class StridePrefetcher(QueuedPrefetcher):
     type = 'StridePrefetcher'
     cxx_class = 'Prefetcher::Stride'
@@ -154,15 +159,18 @@
     confidence_threshold = Param.Percent(50,
         "Prefetch generation confidence threshold")

-    table_sets = Param.Int(16, "Number of sets in PC lookup table")
-    table_assoc = Param.Int(4, "Associativity of PC lookup table")
     use_master_id = Param.Bool(True, "Use master id based history")

     degree = Param.Int(4, "Number of prefetches to generate")

-    # Get replacement policy
-    replacement_policy = Param.BaseReplacementPolicy(RandomRP(),
-        "Replacement policy")
+    table_assoc = Param.Int(4, "Associativity of the PC table")
+ table_entries = Param.MemorySize("64", "Number of entries of the PC table")
+    table_indexing_policy = Param.BaseIndexingPolicy(
+        StridePrefetcherHashedSetAssociative(entry_size = 1,
+        assoc = Parent.table_assoc, size = Parent.table_entries),
+        "Indexing policy of the PC table")
+    table_replacement_policy = Param.BaseReplacementPolicy(RandomRP(),
+        "Replacement policy of the PC table")

 class TaggedPrefetcher(QueuedPrefetcher):
     type = 'TaggedPrefetcher'
diff --git a/src/mem/cache/prefetch/stride.cc b/src/mem/cache/prefetch/stride.cc
index 101adf2..36773c6 100644
--- a/src/mem/cache/prefetch/stride.cc
+++ b/src/mem/cache/prefetch/stride.cc
@@ -53,13 +53,14 @@
 #include "base/random.hh"
 #include "base/trace.hh"
 #include "debug/HWPrefetch.hh"
+#include "mem/cache/prefetch/associative_set_impl.hh"
 #include "mem/cache/replacement_policies/base.hh"
 #include "params/StridePrefetcher.hh"

 namespace Prefetcher {

 Stride::StrideEntry::StrideEntry(const SatCounter& init_confidence)
-  : ReplaceableEntry(), confidence(init_confidence)
+  : TaggedEntry(), confidence(init_confidence)
 {
     invalidate();
 }
@@ -67,9 +68,7 @@
 void
 Stride::StrideEntry::invalidate()
 {
-    instAddr = 0;
     lastAddr = 0;
-    isSecure = false;
     stride = 0;
     confidence.reset();
 }
@@ -78,13 +77,11 @@
   : Queued(p),
     initConfidence(p->confidence_counter_bits, p->initial_confidence),
     threshConf(p->confidence_threshold/100.0),
-    pcTableAssoc(p->table_assoc),
-    pcTableSets(p->table_sets),
     useMasterId(p->use_master_id),
     degree(p->degree),
-    replacementPolicy(p->replacement_policy)
+    pcTableInfo(p->table_assoc, p->table_entries, p->table_indexing_policy,
+        p->table_replacement_policy)
 {
-    assert(isPowerOf2(pcTableSets));
 }

 Stride::PCTable*
@@ -104,7 +101,8 @@
 {
     // Create new table
     auto insertion_result = pcTables.insert(std::make_pair(context,
-        PCTable(pcTableAssoc, pcTableSets, name(), replacementPolicy,
+        PCTable(pcTableInfo.assoc, pcTableInfo.numEntries,
+        pcTableInfo.indexingPolicy, pcTableInfo.replacementPolicy,
         StrideEntry(initConfidence))));

DPRINTF(HWPrefetch, "Adding context %i with stride entries\n", context);
@@ -113,28 +111,6 @@
     return &(insertion_result.first->second);
 }

-Stride::PCTable::PCTable(int assoc, int sets, const std::string name,
-    BaseReplacementPolicy* replacementPolicy, StrideEntry init_confidence)
-    : pcTableSets(sets), _name(name), entries(pcTableSets),
-      replacementPolicy(replacementPolicy)
-{
-    for (int set = 0; set < sets; set++) {
-        entries[set].resize(assoc, init_confidence);
-        for (int way = 0; way < assoc; way++) {
-            // Inform the entry its position
-            entries[set][way].setPosition(set, way);
-
-            // Initialize replacement policy data
-            entries[set][way].replacementData =
-                replacementPolicy->instantiateEntry();
-        }
-    }
-}
-
-Stride::PCTable::~PCTable()
-{
-}
-
 void
 Stride::calculatePrefetch(const PrefetchInfo &pfi,
                                     std::vector<AddrPriority> &addresses)
@@ -157,6 +133,8 @@
     StrideEntry *entry = pcTable->findEntry(pc, is_secure);

     if (entry != nullptr) {
+        pcTable->accessEntry(entry);
+
         // Hit in table
         int new_stride = pf_addr - entry->lastAddr;
         bool stride_match = (new_stride == entry->stride);
@@ -202,66 +180,34 @@

         StrideEntry* entry = pcTable->findVictim(pc);

-        // Invalidate victim
-        entry->invalidate();
-        replacementPolicy->invalidate(entry->replacementData);
-
         // Insert new entry's data
-        entry->instAddr = pc;
         entry->lastAddr = pf_addr;
-        entry->isSecure = is_secure;
-        replacementPolicy->reset(entry->replacementData);
+        pcTable->insertEntry(pc, is_secure, entry);
     }
 }

-inline Addr
-Stride::PCTable::pcHash(Addr pc) const
+inline uint32_t
+StridePrefetcherHashedSetAssociative::extractSet(const Addr pc) const
 {
-    Addr hash1 = pc >> 1;
-    Addr hash2 = hash1 >> floorLog2(pcTableSets);
-    return (hash1 ^ hash2) & (Addr)(pcTableSets - 1);
+    const Addr hash1 = pc >> 1;
+    const Addr hash2 = hash1 >> tagShift;
+    return (hash1 ^ hash2) & setMask;
 }

-inline Stride::StrideEntry*
-Stride::PCTable::findVictim(Addr pc)
+Addr
+StridePrefetcherHashedSetAssociative::extractTag(const Addr addr) const
 {
-    // Rand replacement for now
-    int set = pcHash(pc);
-
-    // Get possible entries to be victimized
-    std::vector<ReplaceableEntry*> possible_entries;
-    for (auto& entry : entries[set]) {
-        possible_entries.push_back(&entry);
-    }
-
-    // Choose victim based on replacement policy
-    StrideEntry* victim = static_cast<StrideEntry*>(
-        replacementPolicy->getVictim(possible_entries));
-
-    DPRINTF(HWPrefetch, "Victimizing lookup table[%d][%d].\n",
-            victim->getSet(), victim->getWay());
-
-    return victim;
-}
-
-inline Stride::StrideEntry*
-Stride::PCTable::findEntry(Addr pc, bool is_secure)
-{
-    int set = pcHash(pc);
-    for (auto& entry : entries[set]) {
-        // Search ways for match
-        if ((entry.instAddr == pc) && (entry.isSecure == is_secure)) {
- DPRINTF(HWPrefetch, "Lookup hit table[%d][%d].\n", entry.getSet(),
-                    entry.getWay());
-            replacementPolicy->touch(entry.replacementData);
-            return &entry;
-        }
-    }
-    return nullptr;
+    return addr;
 }

 } // namespace Prefetcher

+Prefetcher::StridePrefetcherHashedSetAssociative*
+StridePrefetcherHashedSetAssociativeParams::create()
+{
+    return new Prefetcher::StridePrefetcherHashedSetAssociative(this);
+}
+
 Prefetcher::Stride*
 StridePrefetcherParams::create()
 {
diff --git a/src/mem/cache/prefetch/stride.hh b/src/mem/cache/prefetch/stride.hh
index 090c13a..72e335b 100644
--- a/src/mem/cache/prefetch/stride.hh
+++ b/src/mem/cache/prefetch/stride.hh
@@ -53,15 +53,38 @@

 #include "base/sat_counter.hh"
 #include "base/types.hh"
+#include "mem/cache/prefetch/associative_set.hh"
 #include "mem/cache/prefetch/queued.hh"
 #include "mem/cache/replacement_policies/replaceable_entry.hh"
+#include "mem/cache/tags/indexing_policies/set_associative.hh"
 #include "mem/packet.hh"
+#include "params/StridePrefetcherHashedSetAssociative.hh"

+class BaseIndexingPolicy;
 class BaseReplacementPolicy;
 struct StridePrefetcherParams;

 namespace Prefetcher {

+/**
+ * Override the default set associative to apply a specific hash function
+ * when extracting a set.
+ */
+class StridePrefetcherHashedSetAssociative : public SetAssociative
+{
+  protected:
+    uint32_t extractSet(const Addr addr) const override;
+    Addr extractTag(const Addr addr) const override;
+
+  public:
+    StridePrefetcherHashedSetAssociative(
+        const StridePrefetcherHashedSetAssociativeParams *p)
+      : SetAssociative(p)
+    {
+    }
+    ~StridePrefetcherHashedSetAssociative() = default;
+};
+
 class Stride : public Queued
 {
   protected:
@@ -71,86 +94,43 @@
     /** Confidence threshold for prefetch generation. */
     const double threshConf;

-    const int pcTableAssoc;
-    const int pcTableSets;
-
     const bool useMasterId;

     const int degree;

-    /** Replacement policy used in the PC tables. */
-    BaseReplacementPolicy* replacementPolicy;
+    /**
+ * Information used to create a new PC table. All of them behave equally.
+     */
+    const struct PCTableInfo
+    {
+        const int assoc;
+        const int numEntries;

-    struct StrideEntry : public ReplaceableEntry
+        BaseIndexingPolicy* const indexingPolicy;
+        BaseReplacementPolicy* const replacementPolicy;
+
+        PCTableInfo(int assoc, int num_entries,
+            BaseIndexingPolicy* indexing_policy,
+            BaseReplacementPolicy* replacement_policy)
+          : assoc(assoc), numEntries(num_entries),
+            indexingPolicy(indexing_policy),
+            replacementPolicy(replacement_policy)
+        {
+        }
+    } pcTableInfo;
+
+    /** Tagged by hashed PCs. */
+    struct StrideEntry : public TaggedEntry
     {
         StrideEntry(const SatCounter& init_confidence);

-        /** Invalidate the entry */
-        void invalidate();
+        void invalidate() override;

-        Addr instAddr;
         Addr lastAddr;
-        bool isSecure;
         int stride;
         SatCounter confidence;
     };
-
-    class PCTable
-    {
-      public:
-        /**
-         * 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.
-         * @param replacementPolicy Replacement policy used by the table.
-         */
-        PCTable(int assoc, int sets, const std::string name,
-                BaseReplacementPolicy* replacementPolicy,
-                StrideEntry init_confidence);
-
-        /**
-         * Default destructor.
-         */
-        ~PCTable();
-
-        /**
-         * 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);
-
-      private:
-        const std::string name() {return _name; }
-        const int pcTableSets;
-        const std::string _name;
-        std::vector<std::vector<StrideEntry>> entries;
-
-        /**
-         * Replacement policy used by StridePrefetcher.
-         */
-        BaseReplacementPolicy* replacementPolicy;
-
-        /**
-         * 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;
-    };
+    typedef AssociativeSet<StrideEntry> PCTable;
     std::unordered_map<int, PCTable> pcTables;

     /**
diff --git a/src/mem/cache/tags/indexing_policies/base.hh b/src/mem/cache/tags/indexing_policies/base.hh
index 435a078..9a56b54 100644
--- a/src/mem/cache/tags/indexing_policies/base.hh
+++ b/src/mem/cache/tags/indexing_policies/base.hh
@@ -133,7 +133,7 @@
      * @param addr The address to get the tag from.
      * @return The tag of the address.
      */
-    Addr extractTag(const Addr addr) const;
+    virtual Addr extractTag(const Addr addr) const;

     /**
* Find all possible entries for insertion and replacement of an address. diff --git a/src/mem/cache/tags/indexing_policies/set_associative.hh b/src/mem/cache/tags/indexing_policies/set_associative.hh
index 7bfa654..e7126c3 100644
--- a/src/mem/cache/tags/indexing_policies/set_associative.hh
+++ b/src/mem/cache/tags/indexing_policies/set_associative.hh
@@ -78,14 +78,14 @@
  */
 class SetAssociative : public BaseIndexingPolicy
 {
-  private:
+  protected:
     /**
      * Apply a hash function to calculate address set.
      *
      * @param addr The address to calculate the set for.
      * @return The set index for given combination of address and way.
      */
-    uint32_t extractSet(const Addr addr) const;
+    virtual uint32_t extractSet(const Addr addr) const;

   public:
     /**

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/24603
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I19a86cb3c4b40031fef427d5f7eed9d5c5673a44
Gerrit-Change-Number: 24603
Gerrit-PatchSet: 3
Gerrit-Owner: Daniel Carvalho <oda...@yahoo.com.br>
Gerrit-Reviewer: Daniel Carvalho <oda...@yahoo.com.br>
Gerrit-Reviewer: Nikos Nikoleris <nikos.nikole...@arm.com>
Gerrit-Reviewer: kokoro <noreply+kok...@google.com>
Gerrit-MessageType: merged
_______________________________________________
gem5-dev mailing list -- gem5-dev@gem5.org
To unsubscribe send an email to gem5-dev-le...@gem5.org
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s

Reply via email to