Daniel Carvalho has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/37897 )

Change subject: mem-cache: Implement a dueling Replacement Policy
......................................................................

mem-cache: Implement a dueling Replacement Policy

Implement a template dueling replacement policy which monitors
two replacement policies to decide and select the one that
provides the least amount of misses.

Change-Id: I6a6e96a9388cce8f8c8cd7b9c1dbe9f0554ccc64
Signed-off-by: Daniel R. Carvalho <[email protected]>
---
M src/mem/cache/replacement_policies/ReplacementPolicies.py
M src/mem/cache/replacement_policies/SConscript
M src/mem/cache/replacement_policies/base.hh
A src/mem/cache/replacement_policies/dueling_rp.cc
A src/mem/cache/replacement_policies/dueling_rp.hh
5 files changed, 273 insertions(+), 1 deletion(-)



diff --git a/src/mem/cache/replacement_policies/ReplacementPolicies.py b/src/mem/cache/replacement_policies/ReplacementPolicies.py
index 06a4909..14ce51e 100644
--- a/src/mem/cache/replacement_policies/ReplacementPolicies.py
+++ b/src/mem/cache/replacement_policies/ReplacementPolicies.py
@@ -34,6 +34,20 @@
     cxx_class = 'ReplacementPolicy::Base'
     cxx_header = "mem/cache/replacement_policies/base.hh"

+class DuelingRP(BaseReplacementPolicy):
+    type = 'DuelingRP'
+    cxx_class = 'ReplacementPolicy::Dueling'
+    cxx_header = "mem/cache/replacement_policies/dueling_rp.hh"
+
+    constituency_size = Param.Unsigned(
+        "The size of a region containing one sample")
+    team_size = Param.Unsigned(
+        "Number of entries in a sampling set that belong to a team")
+    replacement_policy_a = Param.BaseReplacementPolicy(
+        "Sub-replacement policy A")
+    replacement_policy_b = Param.BaseReplacementPolicy(
+        "Sub-replacement policy B")
+
 class FIFORP(BaseReplacementPolicy):
     type = 'FIFORP'
     cxx_class = 'ReplacementPolicy::FIFO'
diff --git a/src/mem/cache/replacement_policies/SConscript b/src/mem/cache/replacement_policies/SConscript
index 2537d22..29152a0 100644
--- a/src/mem/cache/replacement_policies/SConscript
+++ b/src/mem/cache/replacement_policies/SConscript
@@ -32,6 +32,7 @@

 Source('bip_rp.cc')
 Source('brrip_rp.cc')
+Source('dueling_rp.cc')
 Source('fifo_rp.cc')
 Source('lfu_rp.cc')
 Source('lru_rp.cc')
diff --git a/src/mem/cache/replacement_policies/base.hh b/src/mem/cache/replacement_policies/base.hh
index 61bf6e8..d5673ec 100644
--- a/src/mem/cache/replacement_policies/base.hh
+++ b/src/mem/cache/replacement_policies/base.hh
@@ -39,12 +39,16 @@

 namespace ReplacementPolicy {

+class Dueling;
+
 /**
  * A common base class of cache replacement policy objects.
  */
 class Base : public SimObject
 {
   protected:
+    friend Dueling;
+
     /**
      * Replacement candidates as chosen by the indexing policy. Although
      * the entry contains its replacemnt data, when using dynamic sampling
@@ -126,7 +130,7 @@
* @param candidates Replacement candidates, selected by indexing policy.
      * @return Replacement entry to be replaced.
      */
-    ReplaceableEntry*
+    virtual ReplaceableEntry*
     getVictim(const std::vector<ReplaceableEntry*>& candidates) const
     {
         ReplacementCandidates replacement_candidates;
diff --git a/src/mem/cache/replacement_policies/dueling_rp.cc b/src/mem/cache/replacement_policies/dueling_rp.cc
new file mode 100644
index 0000000..59c8990
--- /dev/null
+++ b/src/mem/cache/replacement_policies/dueling_rp.cc
@@ -0,0 +1,142 @@
+/**
+ * Copyright (c) 2019, 2020 Inria
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "mem/cache/replacement_policies/dueling_rp.hh"
+
+#include "base/logging.hh"
+#include "params/DuelingRP.hh"
+
+namespace ReplacementPolicy {
+
+Dueling::Dueling(const Params &p)
+  : Base(p), replPolicyA(p.replacement_policy_a),
+    replPolicyB(p.replacement_policy_b),
+    duelingMonitor(p.constituency_size, p.team_size),
+    duelingStats(this)
+{
+    fatal_if((replPolicyA == nullptr) || (replPolicyB == nullptr),
+        "All replacement policies must be instantiated");
+}
+
+void
+Dueling::invalidate(
+    const std::shared_ptr<ReplacementData>& replacement_data) const
+{
+    std::shared_ptr<DuelerReplData> casted_replacement_data =
+        std::static_pointer_cast<DuelerReplData>(replacement_data);
+    replPolicyA->invalidate(casted_replacement_data->replDataA);
+    replPolicyB->invalidate(casted_replacement_data->replDataB);
+}
+
+void
+Dueling::touch(const std::shared_ptr<ReplacementData>& replacement_data) const
+{
+    std::shared_ptr<DuelerReplData> casted_replacement_data =
+        std::static_pointer_cast<DuelerReplData>(replacement_data);
+    replPolicyA->touch(casted_replacement_data->replDataA);
+    replPolicyB->touch(casted_replacement_data->replDataB);
+}
+
+void
+Dueling::reset(const std::shared_ptr<ReplacementData>& replacement_data) const
+{
+    std::shared_ptr<DuelerReplData> casted_replacement_data =
+        std::static_pointer_cast<DuelerReplData>(replacement_data);
+    replPolicyA->reset(casted_replacement_data->replDataA);
+    replPolicyB->reset(casted_replacement_data->replDataB);
+
+    // A miss in a set is a sample to the duel. A call to this function
+    // implies in the replacement of an entry, which was either caused by
+    // a miss, an external invalidation, or the initialization of the table
+    // entry (when warming up)
+ duelingMonitor.sample(static_cast<Dueler*>(casted_replacement_data.get()));
+}
+
+ReplaceableEntry*
+Dueling::getVictim(ReplacementCandidates& candidates) const
+{
+    panic("This function should not be called");
+    return nullptr;
+}
+
+ReplaceableEntry*
+Dueling::getVictim(const std::vector<ReplaceableEntry*>& candidates) const
+{
+    // The team with the most misses loses
+    bool winner = !duelingMonitor.getWinner();
+
+    // If the entry is a sample, it can only be used with a certain policy.
+    // This assumes that all candidates are either part of the same sampled
+    // set, or are not samples.
+    bool team;
+    bool is_sample = duelingMonitor.isSample(static_cast<Dueler*>(
+        std::static_pointer_cast<DuelerReplData>(
+            candidates[0]->replacementData).get()), team);
+
+    // All replacement candidates must be set appropriately, so that the
+    // proper replacement data is used. A replacement policy X must be used
+    // if the candidates are its samples - in which case they must always
+    // use X - or if it is not a sample, and X is currently the best RP
+    if ((is_sample && team) || (!is_sample && winner)) {
+        duelingStats.selectedA++;
+        ReplacementCandidates candidates_a;
+        for (auto& candidate : candidates) {
+            auto repl_data = std::static_pointer_cast<DuelerReplData>(
+                candidate->replacementData)->replDataA;
+ candidates_a.push_back(ReplacementCandidate(repl_data, candidate));
+        }
+        return replPolicyA->getVictim(candidates_a);
+    } else {
+        duelingStats.selectedB++;
+        ReplacementCandidates candidates_b;
+        for (auto& candidate : candidates) {
+            auto repl_data = std::static_pointer_cast<DuelerReplData>(
+                candidate->replacementData)->replDataB;
+ candidates_b.push_back(ReplacementCandidate(repl_data, candidate));
+        }
+        return replPolicyB->getVictim(candidates_b);
+    }
+}
+
+std::shared_ptr<ReplacementData>
+Dueling::instantiateEntry()
+{
+    DuelerReplData* replacement_data = new DuelerReplData(
+        replPolicyA->instantiateEntry(), replPolicyB->instantiateEntry());
+    duelingMonitor.initEntry(static_cast<Dueler*>(replacement_data));
+    return std::shared_ptr<DuelerReplData>(replacement_data);
+}
+
+Dueling::DuelingStats::DuelingStats(Stats::Group* parent)
+  : Stats::Group(parent),
+    ADD_STAT(selectedA, "Number of times A was selected to victimize"),
+    ADD_STAT(selectedB, "Number of times B was selected to victimize")
+{
+}
+
+} // namespace ReplacementPolicy
diff --git a/src/mem/cache/replacement_policies/dueling_rp.hh b/src/mem/cache/replacement_policies/dueling_rp.hh
new file mode 100644
index 0000000..55627bf
--- /dev/null
+++ b/src/mem/cache/replacement_policies/dueling_rp.hh
@@ -0,0 +1,111 @@
+/**
+ * Copyright (c) 2019, 2020 Inria
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __MEM_CACHE_REPLACEMENT_POLICIES_DUELING_RP_HH__
+#define __MEM_CACHE_REPLACEMENT_POLICIES_DUELING_RP_HH__
+
+#include <memory>
+
+#include "base/dueling.hh"
+#include "base/statistics.hh"
+#include "mem/cache/replacement_policies/base.hh"
+
+struct DuelingRPParams;
+
+namespace ReplacementPolicy {
+
+/**
+ * This replacement policy duels two replacement policies to find out which
+ * one provides the best results. A policy is said to have the best results
+ * when it has a lower number of misses.
+ */
+class Dueling : public Base
+{
+  protected:
+    /**
+     * Dueler-specific implementation of replacement data. Contains all
+     * sub-replacement policies' replacement data.
+     */
+    struct DuelerReplData : ReplacementData, Dueler
+    {
+        std::shared_ptr<ReplacementData> replDataA;
+        std::shared_ptr<ReplacementData> replDataB;
+
+        /** Default constructor. Initialize sub-replacement data. */
+        DuelerReplData(const std::shared_ptr<ReplacementData>& repl_data_a,
+            const std::shared_ptr<ReplacementData>& repl_data_b)
+          : ReplacementData(), Dueler(), replDataA(repl_data_a),
+            replDataB(repl_data_b)
+        {
+        }
+    };
+
+    /** Sub-replacement policy used in this multiple container. */
+    Base* const replPolicyA;
+    /** Sub-replacement policy used in this multiple container. */
+    Base* const replPolicyB;
+
+    /**
+     * A dueling monitor that decides which is the best sub-policy based on
+     * their number of misses.
+     */
+    mutable DuelingMonitor duelingMonitor;
+
+    mutable struct DuelingStats : public Stats::Group
+    {
+        DuelingStats(Stats::Group* parent);
+
+        /** Number of times A was selected on victimization. */
+        Stats::Scalar selectedA;
+
+        /** Number of times B was selected on victimization. */
+        Stats::Scalar selectedB;
+    } duelingStats;
+
+    ReplaceableEntry* getVictim(ReplacementCandidates& candidates) const
+                                                               override;
+
+  public:
+    typedef DuelingRPParams Params;
+    Dueling(const Params &p);
+    ~Dueling() = default;
+
+ void invalidate(const std::shared_ptr<ReplacementData>& replacement_data) + const override; + void touch(const std::shared_ptr<ReplacementData>& replacement_data) const + override; + void reset(const std::shared_ptr<ReplacementData>& replacement_data) const + override;
+    ReplaceableEntry* getVictim(
+        const std::vector<ReplaceableEntry*>& candidates) const override;
+    std::shared_ptr<ReplacementData> instantiateEntry() override;
+};
+
+} // namespace ReplacementPolicy
+
+#endif // __MEM_CACHE_REPLACEMENT_POLICIES_DUELING_RP_HH__

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/37897
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: I6a6e96a9388cce8f8c8cd7b9c1dbe9f0554ccc64
Gerrit-Change-Number: 37897
Gerrit-PatchSet: 1
Gerrit-Owner: Daniel Carvalho <[email protected]>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s

Reply via email to