From 153a33be851190acdec443264c3a1f1dfa44592a Mon Sep 17 00:00:00 2001 From: Daniel Date: Sun, 11 Nov 2018 15:52:08 +0100 Subject: [PATCH] mem-cache: Make StridePrefetcher use Replacement Policies Previously StridePrefetcher was only able to use random replacement policy. This change allows all replacement policies to be applied to the pc table. Change-Id: I8714e71a6a4c9c31fbca49a07a456dcacd3e402c Signed-off-by: Daniel Reviewed-on: https://gem5-review.googlesource.com/c/14360 Reviewed-by: Nikos Nikoleris Maintainer: Nikos Nikoleris --- src/mem/cache/prefetch/Prefetcher.py | 5 +++ src/mem/cache/prefetch/stride.cc | 59 ++++++++++++++++++++-------- src/mem/cache/prefetch/stride.hh | 19 +++++++-- 3 files changed, 64 insertions(+), 19 deletions(-) diff --git a/src/mem/cache/prefetch/Prefetcher.py b/src/mem/cache/prefetch/Prefetcher.py index 09717dff7..bae235d84 100644 --- a/src/mem/cache/prefetch/Prefetcher.py +++ b/src/mem/cache/prefetch/Prefetcher.py @@ -43,6 +43,7 @@ from ClockedObject import ClockedObject from m5.SimObject import * from m5.params import * from m5.proxy import * +from ReplacementPolicies import * class HWPProbeEvent(object): def __init__(self, prefetcher, obj, *listOfNames): @@ -126,6 +127,10 @@ class StridePrefetcher(QueuedPrefetcher): degree = Param.Int(4, "Number of prefetches to generate") + # Get replacement policy + replacement_policy = Param.BaseReplacementPolicy(RandomRP(), + "Replacement policy") + class TaggedPrefetcher(QueuedPrefetcher): type = 'TaggedPrefetcher' cxx_class = 'TaggedPrefetcher' diff --git a/src/mem/cache/prefetch/stride.cc b/src/mem/cache/prefetch/stride.cc index 4520f12c2..44849cd57 100644 --- a/src/mem/cache/prefetch/stride.cc +++ b/src/mem/cache/prefetch/stride.cc @@ -1,4 +1,5 @@ /* + * Copyright (c) 2018 Inria * Copyright (c) 2012-2013, 2015 ARM Limited * All rights reserved * @@ -39,6 +40,7 @@ * * Authors: Ron Dreslinski * Steve Reinhardt + * Daniel Carvalho */ /** @@ -55,6 +57,7 @@ #include "base/random.hh" #include "base/trace.hh" #include "debug/HWPrefetch.hh" +#include "mem/cache/replacement_policies/base.hh" #include "params/StridePrefetcher.hh" StridePrefetcher::StrideEntry::StrideEntry() @@ -81,7 +84,8 @@ StridePrefetcher::StridePrefetcher(const StridePrefetcherParams *p) pcTableAssoc(p->table_assoc), pcTableSets(p->table_sets), useMasterId(p->use_master_id), - degree(p->degree) + degree(p->degree), + replacementPolicy(p->replacement_policy) { assert(isPowerOf2(pcTableSets)); } @@ -103,7 +107,7 @@ StridePrefetcher::allocateNewContext(int context) { // Create new table auto insertion_result = pcTables.insert(std::make_pair(context, - PCTable(pcTableAssoc, pcTableSets, name()))); + PCTable(pcTableAssoc, pcTableSets, name(), replacementPolicy))); DPRINTF(HWPrefetch, "Adding context %i with stride entries\n", context); @@ -111,11 +115,21 @@ StridePrefetcher::allocateNewContext(int context) return &(insertion_result.first->second); } -StridePrefetcher::PCTable::PCTable(int assoc, int sets, const std::string name) - : pcTableAssoc(assoc), pcTableSets(sets), _name(name), entries(pcTableSets) +StridePrefetcher::PCTable::PCTable(int assoc, int sets, const std::string name, + BaseReplacementPolicy* replacementPolicy) + : pcTableSets(sets), _name(name), entries(pcTableSets), + replacementPolicy(replacementPolicy) { - for (auto& set : entries) { - set.resize(pcTableAssoc); + for (int set = 0; set < sets; set++) { + entries[set].resize(assoc); + 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(); + } } } @@ -200,12 +214,14 @@ StridePrefetcher::calculatePrefetch(const PacketPtr &pkt, // Invalidate victim entry->invalidate(); + replacementPolicy->invalidate(entry->replacementData); // Insert new entry's data entry->instAddr = pc; entry->lastAddr = pkt_addr; - entry->isSecure= is_secure; + entry->isSecure = is_secure; entry->confidence = startConf; + replacementPolicy->reset(entry->replacementData); } } @@ -222,23 +238,34 @@ StridePrefetcher::PCTable::findVictim(Addr pc) { // Rand replacement for now int set = pcHash(pc); - int way = random_mt.random(0, pcTableAssoc - 1); - DPRINTF(HWPrefetch, "Victimizing lookup table[%d][%d].\n", set, way); - return &entries[set][way]; + // Get possible entries to be victimized + std::vector possible_entries; + for (auto& entry : entries[set]) { + possible_entries.push_back(&entry); + } + + // Choose victim based on replacement policy + StrideEntry* victim = static_cast( + replacementPolicy->getVictim(possible_entries)); + + DPRINTF(HWPrefetch, "Victimizing lookup table[%d][%d].\n", + victim->getSet(), victim->getWay()); + + return victim; } inline StridePrefetcher::StrideEntry* StridePrefetcher::PCTable::findEntry(Addr pc, bool is_secure) { int set = pcHash(pc); - std::vector& set_entries = entries[set]; - for (int way = 0; way < pcTableAssoc; way++) { - StrideEntry* entry = &set_entries[way]; + 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", set, way); - return entry; + 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; diff --git a/src/mem/cache/prefetch/stride.hh b/src/mem/cache/prefetch/stride.hh index 772c3a511..aa0228705 100644 --- a/src/mem/cache/prefetch/stride.hh +++ b/src/mem/cache/prefetch/stride.hh @@ -1,4 +1,5 @@ /* + * Copyright (c) 2018 Inria * Copyright (c) 2012-2013, 2015 ARM Limited * All rights reserved * @@ -38,6 +39,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Authors: Ron Dreslinski + * Daniel Carvalho */ /** @@ -54,8 +56,10 @@ #include "base/types.hh" #include "mem/cache/prefetch/queued.hh" +#include "mem/cache/replacement_policies/replaceable_entry.hh" #include "mem/packet.hh" +class BaseReplacementPolicy; struct StridePrefetcherParams; class StridePrefetcher : public QueuedPrefetcher @@ -73,7 +77,10 @@ class StridePrefetcher : public QueuedPrefetcher const int degree; - struct StrideEntry + /** Replacement policy used in the PC tables. */ + BaseReplacementPolicy* replacementPolicy; + + struct StrideEntry : public ReplaceableEntry { /** Default constructor */ StrideEntry(); @@ -97,8 +104,10 @@ class StridePrefetcher : public QueuedPrefetcher * @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); + PCTable(int assoc, int sets, const std::string name, + BaseReplacementPolicy* replacementPolicy); /** * Default destructor. @@ -124,11 +133,15 @@ class StridePrefetcher : public QueuedPrefetcher private: const std::string name() {return _name; } - const int pcTableAssoc; const int pcTableSets; const std::string _name; std::vector> entries; + /** + * Replacement policy used by StridePrefetcher. + */ + BaseReplacementPolicy* replacementPolicy; + /** * PC hashing function to index sets in the table. * -- 2.30.2