mem-cache: Use SatCounter in Stride prefetcher
There is no need to reimplement saturating counter functionality.
Change-Id: Ie7753089873f41a378ab88fd5f095302c3428797
Signed-off-by: Daniel R. Carvalho <odanrc@yahoo.com.br>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/24542
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Maintainer: Nikos Nikoleris <nikos.nikoleris@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
diff --git a/src/mem/cache/prefetch/Prefetcher.py b/src/mem/cache/prefetch/Prefetcher.py
index 8cfefe1..51132f9 100644
--- a/src/mem/cache/prefetch/Prefetcher.py
+++ b/src/mem/cache/prefetch/Prefetcher.py
@@ -147,10 +147,12 @@
# Do not consult stride prefetcher on instruction accesses
on_inst = False
- max_conf = Param.Int(7, "Maximum confidence level")
- thresh_conf = Param.Int(4, "Threshold confidence level")
- min_conf = Param.Int(0, "Minimum confidence level")
- start_conf = Param.Int(4, "Starting confidence for new entries")
+ confidence_counter_bits = Param.Unsigned(3,
+ "Number of bits of the confidence counter")
+ initial_confidence = Param.Unsigned(4,
+ "Starting confidence of new entries")
+ 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")
diff --git a/src/mem/cache/prefetch/stride.cc b/src/mem/cache/prefetch/stride.cc
index 8e47d9b..101adf2 100644
--- a/src/mem/cache/prefetch/stride.cc
+++ b/src/mem/cache/prefetch/stride.cc
@@ -58,7 +58,8 @@
namespace Prefetcher {
-Stride::StrideEntry::StrideEntry()
+Stride::StrideEntry::StrideEntry(const SatCounter& init_confidence)
+ : ReplaceableEntry(), confidence(init_confidence)
{
invalidate();
}
@@ -70,20 +71,18 @@
lastAddr = 0;
isSecure = false;
stride = 0;
- confidence = 0;
+ confidence.reset();
}
Stride::Stride(const StridePrefetcherParams *p)
- : Queued(p),
- maxConf(p->max_conf),
- threshConf(p->thresh_conf),
- minConf(p->min_conf),
- startConf(p->start_conf),
- pcTableAssoc(p->table_assoc),
- pcTableSets(p->table_sets),
- useMasterId(p->use_master_id),
- degree(p->degree),
- replacementPolicy(p->replacement_policy)
+ : 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)
{
assert(isPowerOf2(pcTableSets));
}
@@ -105,7 +104,8 @@
{
// Create new table
auto insertion_result = pcTables.insert(std::make_pair(context,
- PCTable(pcTableAssoc, pcTableSets, name(), replacementPolicy)));
+ PCTable(pcTableAssoc, pcTableSets, name(), replacementPolicy,
+ StrideEntry(initConfidence))));
DPRINTF(HWPrefetch, "Adding context %i with stride entries\n", context);
@@ -114,12 +114,12 @@
}
Stride::PCTable::PCTable(int assoc, int sets, const std::string name,
- BaseReplacementPolicy* replacementPolicy)
+ BaseReplacementPolicy* replacementPolicy, StrideEntry init_confidence)
: pcTableSets(sets), _name(name), entries(pcTableSets),
replacementPolicy(replacementPolicy)
{
for (int set = 0; set < sets; set++) {
- entries[set].resize(assoc);
+ entries[set].resize(assoc, init_confidence);
for (int way = 0; way < assoc; way++) {
// Inform the entry its position
entries[set][way].setPosition(set, way);
@@ -163,26 +163,26 @@
// Adjust confidence for stride entry
if (stride_match && new_stride != 0) {
- if (entry->confidence < maxConf)
- entry->confidence++;
+ entry->confidence++;
} else {
- if (entry->confidence > minConf)
- entry->confidence--;
+ entry->confidence--;
// If confidence has dropped below the threshold, train new stride
- if (entry->confidence < threshConf)
+ if (entry->confidence.calcSaturation() < threshConf) {
entry->stride = new_stride;
+ }
}
DPRINTF(HWPrefetch, "Hit: PC %x pkt_addr %x (%s) stride %d (%s), "
"conf %d\n", pc, pf_addr, is_secure ? "s" : "ns",
new_stride, stride_match ? "match" : "change",
- entry->confidence);
+ (int)entry->confidence);
entry->lastAddr = pf_addr;
// Abort prefetch generation if below confidence threshold
- if (entry->confidence < threshConf)
+ if (entry->confidence.calcSaturation() < threshConf) {
return;
+ }
// Generate up to degree prefetches
for (int d = 1; d <= degree; d++) {
@@ -210,7 +210,6 @@
entry->instAddr = pc;
entry->lastAddr = pf_addr;
entry->isSecure = is_secure;
- entry->confidence = startConf;
replacementPolicy->reset(entry->replacementData);
}
}
diff --git a/src/mem/cache/prefetch/stride.hh b/src/mem/cache/prefetch/stride.hh
index f483527..090c13a 100644
--- a/src/mem/cache/prefetch/stride.hh
+++ b/src/mem/cache/prefetch/stride.hh
@@ -51,6 +51,7 @@
#include <unordered_map>
#include <vector>
+#include "base/sat_counter.hh"
#include "base/types.hh"
#include "mem/cache/prefetch/queued.hh"
#include "mem/cache/replacement_policies/replaceable_entry.hh"
@@ -64,10 +65,11 @@
class Stride : public Queued
{
protected:
- const int maxConf;
- const int threshConf;
- const int minConf;
- const int startConf;
+ /** Initial confidence counter value for the pc tables. */
+ const SatCounter initConfidence;
+
+ /** Confidence threshold for prefetch generation. */
+ const double threshConf;
const int pcTableAssoc;
const int pcTableSets;
@@ -81,8 +83,7 @@
struct StrideEntry : public ReplaceableEntry
{
- /** Default constructor */
- StrideEntry();
+ StrideEntry(const SatCounter& init_confidence);
/** Invalidate the entry */
void invalidate();
@@ -91,7 +92,7 @@
Addr lastAddr;
bool isSecure;
int stride;
- int confidence;
+ SatCounter confidence;
};
class PCTable
@@ -106,7 +107,8 @@
* @param replacementPolicy Replacement policy used by the table.
*/
PCTable(int assoc, int sets, const std::string name,
- BaseReplacementPolicy* replacementPolicy);
+ BaseReplacementPolicy* replacementPolicy,
+ StrideEntry init_confidence);
/**
* Default destructor.