summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJavier Bueno <javier.bueno@metempsy.com>2018-12-13 11:38:15 +0100
committerJavier Bueno Hedo <javier.bueno@metempsy.com>2019-02-01 20:54:28 +0000
commit2775f55447edb344d99f30273ad93fea515d7e2b (patch)
treeb1a274a936f8f3a970a1014bda73b2a92c873e0f
parent6684d617da52d1956f955a9452ff90058d66cf9e (diff)
downloadgem5-2775f55447edb344d99f30273ad93fea515d7e2b.tar.xz
mem-cache: Updated version of the Signature Path Prefetcher
This implementation is based in the description available in: Jinchun Kim, Seth H. Pugsley, Paul V. Gratz, A. L. Narasimha Reddy, Chris Wilkerson, and Zeshan Chishti. 2016. Path confidence based lookahead prefetching. In The 49th Annual IEEE/ACM International Symposium on Microarchitecture (MICRO-49). IEEE Press, Piscataway, NJ, USA, Article 60, 12 pages. Change-Id: I4b8b54efef48ced7044bd535de9a69bca68d47d9 Reviewed-on: https://gem5-review.googlesource.com/c/14819 Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com> Maintainer: Nikos Nikoleris <nikos.nikoleris@arm.com>
-rw-r--r--src/mem/cache/base.hh9
-rw-r--r--src/mem/cache/prefetch/Prefetcher.py23
-rw-r--r--src/mem/cache/prefetch/SConscript1
-rw-r--r--src/mem/cache/prefetch/base.cc13
-rw-r--r--src/mem/cache/prefetch/base.hh7
-rw-r--r--src/mem/cache/prefetch/queued.cc1
-rw-r--r--src/mem/cache/prefetch/signature_path.cc153
-rw-r--r--src/mem/cache/prefetch/signature_path.hh109
-rw-r--r--src/mem/cache/prefetch/signature_path_v2.cc136
-rw-r--r--src/mem/cache/prefetch/signature_path_v2.hh97
10 files changed, 488 insertions, 61 deletions
diff --git a/src/mem/cache/base.hh b/src/mem/cache/base.hh
index 70b3d3e45..6144fd584 100644
--- a/src/mem/cache/base.hh
+++ b/src/mem/cache/base.hh
@@ -1132,6 +1132,15 @@ class BaseCache : public MemObject
return tags->findBlock(addr, is_secure);
}
+ bool hasBeenPrefetched(Addr addr, bool is_secure) const {
+ CacheBlk *block = tags->findBlock(addr, is_secure);
+ if (block) {
+ return block->wasPrefetched();
+ } else {
+ return false;
+ }
+ }
+
bool inMissQueue(Addr addr, bool is_secure) const {
return mshrQueue.findMatch(addr, is_secure);
}
diff --git a/src/mem/cache/prefetch/Prefetcher.py b/src/mem/cache/prefetch/Prefetcher.py
index 3d9c66565..082590853 100644
--- a/src/mem/cache/prefetch/Prefetcher.py
+++ b/src/mem/cache/prefetch/Prefetcher.py
@@ -180,6 +180,29 @@ class SignaturePathPrefetcher(QueuedPrefetcher):
lookahead_confidence_threshold = Param.Float(0.75,
"Minimum confidence to continue exploring lookahead entries")
+class SignaturePathPrefetcherV2(SignaturePathPrefetcher):
+ type = 'SignaturePathPrefetcherV2'
+ cxx_class = 'SignaturePathPrefetcherV2'
+ cxx_header = "mem/cache/prefetch/signature_path_v2.hh"
+
+ signature_table_entries = "256"
+ signature_table_assoc = 1
+ pattern_table_entries = "512"
+ pattern_table_assoc = 1
+ max_counter_value = 15
+ prefetch_confidence_threshold = 0.25
+ lookahead_confidence_threshold = 0.25
+
+ global_history_register_entries = Param.MemorySize("8",
+ "Number of entries of global history register")
+ global_history_register_indexing_policy = Param.BaseIndexingPolicy(
+ SetAssociative(entry_size = 1,
+ assoc = Parent.global_history_register_entries,
+ size = Parent.global_history_register_entries),
+ "Indexing policy of the global history register")
+ global_history_register_replacement_policy = Param.BaseReplacementPolicy(
+ LRURP(), "Replacement policy of the global history register")
+
class AccessMapPatternMatchingPrefetcher(QueuedPrefetcher):
type = 'AccessMapPatternMatchingPrefetcher'
cxx_class = 'AccessMapPatternMatchingPrefetcher'
diff --git a/src/mem/cache/prefetch/SConscript b/src/mem/cache/prefetch/SConscript
index b46158624..f9582b580 100644
--- a/src/mem/cache/prefetch/SConscript
+++ b/src/mem/cache/prefetch/SConscript
@@ -36,5 +36,6 @@ Source('access_map_pattern_matching.cc')
Source('base.cc')
Source('queued.cc')
Source('signature_path.cc')
+Source('signature_path_v2.cc')
Source('stride.cc')
Source('tagged.cc')
diff --git a/src/mem/cache/prefetch/base.cc b/src/mem/cache/prefetch/base.cc
index e58d4f3d5..cd3eade09 100644
--- a/src/mem/cache/prefetch/base.cc
+++ b/src/mem/cache/prefetch/base.cc
@@ -81,7 +81,8 @@ BasePrefetcher::BasePrefetcher(const BasePrefetcherParams *p)
onWrite(p->on_write), onData(p->on_data), onInst(p->on_inst),
masterId(p->sys->getMasterId(this)), pageBytes(p->sys->getPageBytes()),
prefetchOnAccess(p->prefetch_on_access),
- useVirtualAddresses(p->use_virtual_addresses)
+ useVirtualAddresses(p->use_virtual_addresses), issuedPrefetches(0),
+ usefulPrefetches(0)
{
}
@@ -146,6 +147,12 @@ BasePrefetcher::inMissQueue(Addr addr, bool is_secure) const
}
bool
+BasePrefetcher::hasBeenPrefetched(Addr addr, bool is_secure) const
+{
+ return cache->hasBeenPrefetched(addr, is_secure);
+}
+
+bool
BasePrefetcher::samePage(Addr a, Addr b) const
{
return roundDown(a, pageBytes) == roundDown(b, pageBytes);
@@ -190,6 +197,10 @@ BasePrefetcher::probeNotify(const PacketPtr &pkt)
if (pkt->req->isCacheMaintenance()) return;
if (pkt->isWrite() && cache != nullptr && cache->coalesce()) return;
+ if (hasBeenPrefetched(pkt->getAddr(), pkt->isSecure())) {
+ usefulPrefetches += 1;
+ }
+
// Verify this access type is observed by prefetcher
if (observeAccess(pkt)) {
if (useVirtualAddresses && pkt->req->hasVaddr()) {
diff --git a/src/mem/cache/prefetch/base.hh b/src/mem/cache/prefetch/base.hh
index 63b0e1bed..06f77492d 100644
--- a/src/mem/cache/prefetch/base.hh
+++ b/src/mem/cache/prefetch/base.hh
@@ -214,6 +214,8 @@ class BasePrefetcher : public ClockedObject
/** Determine if address is in cache miss queue */
bool inMissQueue(Addr addr, bool is_secure) const;
+ bool hasBeenPrefetched(Addr addr, bool is_secure) const;
+
/** Determine if addresses are on the same page */
bool samePage(Addr a, Addr b) const;
/** Determine the address of the block in which a lays */
@@ -229,6 +231,11 @@ class BasePrefetcher : public ClockedObject
Stats::Scalar pfIssued;
+ /** Total prefetches issued */
+ uint64_t issuedPrefetches;
+ /** Total prefetches that has been useful */
+ uint64_t usefulPrefetches;
+
public:
BasePrefetcher(const BasePrefetcherParams *p);
diff --git a/src/mem/cache/prefetch/queued.cc b/src/mem/cache/prefetch/queued.cc
index bce6fbb97..d7b8aacd0 100644
--- a/src/mem/cache/prefetch/queued.cc
+++ b/src/mem/cache/prefetch/queued.cc
@@ -124,6 +124,7 @@ QueuedPrefetcher::getPacket()
pfq.pop_front();
pfIssued++;
+ issuedPrefetches += 1;
assert(pkt != nullptr);
DPRINTF(HWPrefetch, "Generating prefetch for %#x.\n", pkt->getAddr());
return pkt;
diff --git a/src/mem/cache/prefetch/signature_path.cc b/src/mem/cache/prefetch/signature_path.cc
index a0356b1d1..857354e65 100644
--- a/src/mem/cache/prefetch/signature_path.cc
+++ b/src/mem/cache/prefetch/signature_path.cc
@@ -53,6 +53,14 @@ SignaturePathPrefetcher::SignaturePathPrefetcher(
p->pattern_table_replacement_policy,
PatternEntry(stridesPerPatternEntry))
{
+ fatal_if(prefetchConfidenceThreshold < 0,
+ "The prefetch confidence threshold must be greater than 0\n");
+ fatal_if(prefetchConfidenceThreshold > 1,
+ "The prefetch confidence threshold must be less than 1\n");
+ fatal_if(lookaheadConfidenceThreshold < 0,
+ "The lookahead confidence threshold must be greater than 0\n");
+ fatal_if(lookaheadConfidenceThreshold > 1,
+ "The lookahead confidence threshold must be less than 1\n");
}
SignaturePathPrefetcher::PatternStrideEntry &
@@ -86,28 +94,34 @@ SignaturePathPrefetcher::PatternEntry::getStrideEntry(stride_t stride,
}
void
-SignaturePathPrefetcher::addPrefetch(Addr ppn, stride_t block,
+SignaturePathPrefetcher::addPrefetch(Addr ppn, stride_t last_block,
+ stride_t delta, double path_confidence, signature_t signature,
bool is_secure, std::vector<AddrPriority> &addresses)
{
- /**
- * block is relative to the provided ppn. Assuming a page size of 4kB and
- * a block size of 64B, the range of the stride of this prefetcher is
- * -63,63 (pageBytes/blkSize) as the last accessed block also ranges from
- * 0,63, the block value is expected to be between -63 and 126
- * Negative block means that we are accessing the lower contiguous page,
- * 64 or greater point to the next contiguous.
- */
- assert(block > -((stride_t)(pageBytes/blkSize)));
- assert(block < 2*((stride_t)(pageBytes/blkSize)));
+ stride_t block = last_block + delta;
Addr pf_ppn;
stride_t pf_block;
if (block < 0) {
- pf_ppn = ppn - 1;
- pf_block = block + (pageBytes/blkSize);
+ stride_t num_cross_pages = 1 + (-block) / (pageBytes/blkSize);
+ if (num_cross_pages > ppn) {
+ // target address smaller than page 0, ignore this request;
+ return;
+ }
+ pf_ppn = ppn - num_cross_pages;
+ pf_block = block + (pageBytes/blkSize) * num_cross_pages;
+ handlePageCrossingLookahead(signature, last_block, delta,
+ path_confidence);
} else if (block >= (pageBytes/blkSize)) {
- pf_ppn = ppn + 1;
- pf_block = block - (pageBytes/blkSize);
+ stride_t num_cross_pages = block / (pageBytes/blkSize);
+ if (MaxAddr/pageBytes < (ppn + num_cross_pages)) {
+ // target address goes beyond MaxAddr, ignore this request;
+ return;
+ }
+ pf_ppn = ppn + num_cross_pages;
+ pf_block = block - (pageBytes/blkSize) * num_cross_pages;
+ handlePageCrossingLookahead(signature, last_block, delta,
+ path_confidence);
} else {
pf_ppn = ppn;
pf_block = block;
@@ -121,6 +135,24 @@ SignaturePathPrefetcher::addPrefetch(Addr ppn, stride_t block,
}
void
+SignaturePathPrefetcher::handleSignatureTableMiss(stride_t current_block,
+ signature_t &new_signature, double &new_conf, stride_t &new_stride)
+{
+ new_signature = current_block;
+ new_conf = 1.0;
+ new_stride = current_block;
+}
+
+void
+SignaturePathPrefetcher::increasePatternEntryCounter(
+ PatternEntry &pattern_entry, PatternStrideEntry &pstride_entry)
+{
+ if (pstride_entry.counter < maxCounterValue) {
+ pstride_entry.counter += 1;
+ }
+}
+
+void
SignaturePathPrefetcher::updatePatternTable(Addr signature, stride_t stride)
{
assert(stride != 0);
@@ -128,28 +160,31 @@ SignaturePathPrefetcher::updatePatternTable(Addr signature, stride_t stride)
PatternEntry &p_entry = getPatternEntry(signature);
PatternStrideEntry &ps_entry = p_entry.getStrideEntry(stride,
maxCounterValue);
- if (ps_entry.counter < maxCounterValue) {
- ps_entry.counter += 1;
- }
+ increasePatternEntryCounter(p_entry, ps_entry);
}
SignaturePathPrefetcher::SignatureEntry &
SignaturePathPrefetcher::getSignatureEntry(Addr ppn, bool is_secure,
- stride_t block, bool &miss)
+ stride_t block, bool &miss, stride_t &stride,
+ double &initial_confidence)
{
SignatureEntry* signature_entry = signatureTable.findEntry(ppn, is_secure);
if (signature_entry != nullptr) {
signatureTable.accessEntry(signature_entry);
miss = false;
+ stride = block - signature_entry->lastBlock;
} else {
signature_entry = signatureTable.findVictim(ppn);
assert(signature_entry != nullptr);
+ // Sets signature_entry->signature, initial_confidence, and stride
+ handleSignatureTableMiss(block, signature_entry->signature,
+ initial_confidence, stride);
+
signatureTable.insertEntry(ppn, is_secure, signature_entry);
- signature_entry->signature = block;
- signature_entry->lastBlock = block;
miss = true;
}
+ signature_entry->lastBlock = block;
return *signature_entry;
}
@@ -170,6 +205,31 @@ SignaturePathPrefetcher::getPatternEntry(Addr signature)
return *pattern_entry;
}
+double
+SignaturePathPrefetcher::calculatePrefetchConfidence(PatternEntry const &sig,
+ PatternStrideEntry const &entry) const
+{
+ return ((double) entry.counter) / maxCounterValue;
+}
+
+double
+SignaturePathPrefetcher::calculateLookaheadConfidence(PatternEntry const &sig,
+ PatternStrideEntry const &lookahead) const
+{
+ double lookahead_confidence;
+ if (lookahead.counter == maxCounterValue) {
+ /**
+ * maximum confidence is 0.95, guaranteeing that
+ * current confidence will eventually fall beyond
+ * the threshold
+ */
+ lookahead_confidence = 0.95;
+ } else {
+ lookahead_confidence = ((double) lookahead.counter / maxCounterValue);
+ }
+ return lookahead_confidence;
+}
+
void
SignaturePathPrefetcher::calculatePrefetch(const PrefetchInfo &pfi,
std::vector<AddrPriority> &addresses)
@@ -179,19 +239,20 @@ SignaturePathPrefetcher::calculatePrefetch(const PrefetchInfo &pfi,
stride_t current_block = (request_addr % pageBytes) / blkSize;
stride_t stride;
bool is_secure = pfi.isSecure();
+ double initial_confidence = 1.0;
// Get the SignatureEntry of this page to:
// - compute the current stride
// - obtain the current signature of accesses
bool miss;
SignatureEntry &signature_entry = getSignatureEntry(ppn, is_secure,
- current_block, miss);
+ current_block, miss, stride, initial_confidence);
+
if (miss) {
// No history for this page, can't continue
return;
}
- stride = current_block - signature_entry.lastBlock;
if (stride == 0) {
// Can't continue with a stride 0
return;
@@ -200,16 +261,17 @@ SignaturePathPrefetcher::calculatePrefetch(const PrefetchInfo &pfi,
// Update the confidence of the current signature
updatePatternTable(signature_entry.signature, stride);
- // Update the current SignatureEntry signature and lastBlock
+ // Update the current SignatureEntry signature
signature_entry.signature =
updateSignature(signature_entry.signature, stride);
- signature_entry.lastBlock = current_block;
signature_t current_signature = signature_entry.signature;
- double current_confidence = 1.0;
+ double current_confidence = initial_confidence;
stride_t current_stride = signature_entry.lastBlock;
- do {
+ // Look for prefetch candidates while the current path confidence is
+ // high enough
+ while (current_confidence > lookaheadConfidenceThreshold) {
// With the updated signature, attempt to generate prefetches
// - search the PatternTable and select all entries with enough
// confidence, these are prefetch candidates
@@ -226,45 +288,40 @@ SignaturePathPrefetcher::calculatePrefetch(const PrefetchInfo &pfi,
lookahead = &entry;
}
double prefetch_confidence =
- (double) entry.counter / maxCounterValue;
+ calculatePrefetchConfidence(*current_pattern_entry, entry);
if (prefetch_confidence >= prefetchConfidenceThreshold) {
assert(entry.stride != 0);
//prefetch candidate
- addPrefetch(ppn, current_stride + entry.stride,
- is_secure, addresses);
+ addPrefetch(ppn, current_stride, entry.stride,
+ current_confidence, current_signature,
+ is_secure, addresses);
}
}
}
+
if (lookahead != nullptr) {
- // If a lookahead was selected, compute its confidence using
- // the counter of its entry and the accumulated confidence
- // if the confidence is high enough, generate a new signature
- double lookahead_confidence;
- if (lookahead->counter == maxCounterValue) {
- // maximum confidence is 0.95, guaranteeing that
- // current confidence will eventually fall beyond
- // the threshold
- lookahead_confidence = 0.95;
- } else {
- lookahead_confidence =
- ((double) lookahead->counter / maxCounterValue);
- }
- current_confidence *= lookahead_confidence;
+ current_confidence *= calculateLookaheadConfidence(
+ *current_pattern_entry, *lookahead);
current_signature =
updateSignature(current_signature, lookahead->stride);
current_stride += lookahead->stride;
} else {
current_confidence = 0.0;
}
- // If the accumulated confidence is high enough, keep repeating
- // this process with the updated signature
}
- while (current_confidence > lookaheadConfidenceThreshold);
+ auxiliaryPrefetcher(ppn, current_block, is_secure, addresses);
+}
+
+void
+SignaturePathPrefetcher::auxiliaryPrefetcher(Addr ppn, stride_t current_block,
+ bool is_secure, std::vector<AddrPriority> &addresses)
+{
if (addresses.empty()) {
// Enable the next line prefetcher if no prefetch candidates are found
- addPrefetch(ppn, current_block + 1, is_secure, addresses);
+ addPrefetch(ppn, current_block, 1, 0.0 /* unused*/, 0 /* unused */,
+ is_secure, addresses);
}
}
diff --git a/src/mem/cache/prefetch/signature_path.hh b/src/mem/cache/prefetch/signature_path.hh
index 0371b56e3..974c02746 100644
--- a/src/mem/cache/prefetch/signature_path.hh
+++ b/src/mem/cache/prefetch/signature_path.hh
@@ -50,6 +50,7 @@ struct SignaturePathPrefetcherParams;
class SignaturePathPrefetcher : public QueuedPrefetcher
{
+ protected:
/** Signature type */
typedef uint16_t signature_t;
/** Stride type */
@@ -96,7 +97,10 @@ class SignaturePathPrefetcher : public QueuedPrefetcher
{
/** group of stides */
std::vector<PatternStrideEntry> strideEntries;
- PatternEntry(size_t num_strides) : strideEntries(num_strides)
+ /** use counter, used by SPPv2 */
+ uint8_t counter;
+ PatternEntry(size_t num_strides) : strideEntries(num_strides),
+ counter(0)
{}
/** Reset the entries to their initial values */
@@ -106,6 +110,7 @@ class SignaturePathPrefetcher : public QueuedPrefetcher
entry.counter = 0;
entry.stride = 0;
}
+ counter = 0;
}
/**
@@ -157,34 +162,44 @@ class SignaturePathPrefetcher : public QueuedPrefetcher
/**
* Generates an address to be prefetched.
* @param ppn page number to prefetch from
- * @param block block number within the page, this value can be negative,
- * which means that the block refered is actualy in the previous
- * page (ppn-1), if the value is greater than (pageBytes/blkSize-1)
- * then the block refers to a block within the next page (ppn+1)
+ * @param last_block last accessed block within the page ppn
+ * @param delta difference, in number of blocks, from the last_block
+ * accessed to the block to prefetch. The block to prefetch is
+ * computed by this formula:
+ * ppn * pageBytes + (last_block + delta) * blkSize
+ * This value can be negative.
+ * @param path_confidence the confidence factor of this prefetch
+ * @param signature the current path signature
* @param is_secure whether this page is inside the secure memory area
- * @param addresses if allowed, the address will be added to this vector
+ * @param addresses addresses to prefetch will be added to this vector
*/
- void addPrefetch(Addr ppn, stride_t block, bool is_secure,
- std::vector<AddrPriority> &addresses);
+ void addPrefetch(Addr ppn, stride_t last_block, stride_t delta,
+ double path_confidence, signature_t signature,
+ bool is_secure,
+ std::vector<AddrPriority> &addresses);
/**
* Obtains the SignatureEntry of the given page, if the page is not found,
* it allocates a new one, replacing an existing entry if needed
+ * It also provides the stride of the current block and the initial
+ * path confidence of the corresponding entry
* @param ppn physical page number of the page
* @param is_secure whether this page is inside the secure memory area
* @param block accessed block within the page
- * @param miss output, if the entry is not found, this will be set to true
+ * @param miss if the entry is not found, this will be set to true
+ * @param stride set to the computed stride
+ * @param initial_confidence set to the initial confidence value
* @result a reference to the SignatureEntry
*/
- SignatureEntry & getSignatureEntry(Addr ppn, bool is_secure,
- stride_t block, bool &miss);
+ SignatureEntry &getSignatureEntry(Addr ppn, bool is_secure, stride_t block,
+ bool &miss, stride_t &stride, double &initial_confidence);
/**
* Obtains the PatternEntry of the given signature, if the signature is
* not found, it allocates a new one, replacing an existing entry if needed
* @param signature the signature of the desired entry
* @result a reference to the PatternEntry
*/
- PatternEntry & getPatternEntry(Addr signature);
+ PatternEntry& getPatternEntry(Addr signature);
/**
* Updates the pattern table with the provided signature and stride
@@ -194,6 +209,76 @@ class SignaturePathPrefetcher : public QueuedPrefetcher
*/
void updatePatternTable(Addr signature, stride_t stride);
+ /**
+ * Computes the lookahead path confidence of the provided pattern entry
+ * @param sig the PatternEntry to use
+ * @param lookahead PatternStrideEntry within the provided PatternEntry
+ * @return the computed confidence factor
+ */
+ virtual double calculateLookaheadConfidence(PatternEntry const &sig,
+ PatternStrideEntry const &lookahead) const;
+
+ /**
+ * Computes the prefetch confidence of the provided pattern entry
+ * @param sig the PatternEntry to use
+ * @param entry PatternStrideEntry within the provided PatternEntry
+ * @return the computed confidence factor
+ */
+ virtual double calculatePrefetchConfidence(PatternEntry const &sig,
+ PatternStrideEntry const &entry) const;
+
+ /**
+ * Increases the counter of a given PatternEntry/PatternStrideEntry
+ * @param pattern_entry the corresponding PatternEntry
+ * @param pstride_entry the PatternStrideEntry within the PatternEntry
+ */
+ virtual void increasePatternEntryCounter(PatternEntry &pattern_entry,
+ PatternStrideEntry &pstride_entry);
+
+ /**
+ * Whenever a new SignatureEntry is allocated, it computes the new
+ * signature to be used with the new entry, the resulting stride and the
+ * initial path confidence of the new entry.
+ * @param current_block accessed block within the page of the associated
+ entry
+ * @param new_signature new signature of the allocated entry
+ * @param new_conf the initial path confidence of this entry
+ * @param new_stride the resulting current stride
+ */
+ virtual void handleSignatureTableMiss(stride_t current_block,
+ signature_t &new_signature, double &new_conf,
+ stride_t &new_stride);
+
+ /**
+ * Auxiliar prefetch mechanism used at the end of calculatePrefetch.
+ * This prefetcher uses this to activate the next line prefetcher if
+ * no prefetch candidates have been found.
+ * @param ppn physical page number of the current accessed page
+ * @param current_block last accessed block within the page ppn
+ * @param is_secure whether this page is inside the secure memory area
+ * @param addresses the addresses to be prefetched are added to this vector
+ * @param updated_filter_entries set of addresses containing these that
+ * their filter has been updated, if this call updates a new entry
+ */
+ virtual void auxiliaryPrefetcher(Addr ppn, stride_t current_block,
+ bool is_secure, std::vector<AddrPriority> &addresses);
+
+ /**
+ * Handles the situation when the lookahead process has crossed the
+ * boundaries of the current page. This is not fully described in the
+ * paper that was used to implement this code, however, the article
+ * describing the upgraded version of this prefetcher provides some
+ * details. For this prefetcher, there are no specific actions to be
+ * done.
+ * @param signature the lookahead signature that crossed the page
+ * @param delta the current stride that caused it
+ * @param last_offset the last accessed block within the page
+ * @param path_confidence the path confidence at the moment of crossing
+ */
+ virtual void handlePageCrossingLookahead(signature_t signature,
+ stride_t last_offset, stride_t delta, double path_confidence) {
+ }
+
public:
SignaturePathPrefetcher(const SignaturePathPrefetcherParams* p);
~SignaturePathPrefetcher() {}
diff --git a/src/mem/cache/prefetch/signature_path_v2.cc b/src/mem/cache/prefetch/signature_path_v2.cc
new file mode 100644
index 000000000..571c3d12b
--- /dev/null
+++ b/src/mem/cache/prefetch/signature_path_v2.cc
@@ -0,0 +1,136 @@
+/**
+ * Copyright (c) 2018 Metempsy Technology Consulting
+ * 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.
+ *
+ * Authors: Javier Bueno
+ */
+
+#include "mem/cache/prefetch/signature_path_v2.hh"
+
+#include <cassert>
+
+#include "debug/HWPrefetch.hh"
+#include "mem/cache/prefetch/associative_set_impl.hh"
+#include "params/SignaturePathPrefetcherV2.hh"
+
+SignaturePathPrefetcherV2::SignaturePathPrefetcherV2(
+ const SignaturePathPrefetcherV2Params *p)
+ : SignaturePathPrefetcher(p),
+ globalHistoryRegister(p->global_history_register_entries,
+ p->global_history_register_entries,
+ p->global_history_register_indexing_policy,
+ p->global_history_register_replacement_policy,
+ GlobalHistoryEntry())
+{
+}
+
+void
+SignaturePathPrefetcherV2::handleSignatureTableMiss(stride_t current_block,
+ signature_t &new_signature, double &new_conf, stride_t &new_stride)
+{
+ bool found = false;
+
+ // This should return all entries of the GHR, since it is a fully
+ // associative table
+ std::vector<GlobalHistoryEntry *> all_ghr_entries =
+ globalHistoryRegister.getPossibleEntries(0 /* any value works */);
+
+ for (auto gh_entry : all_ghr_entries) {
+ if (gh_entry->lastBlock + gh_entry->delta == current_block) {
+ new_signature = gh_entry->signature;
+ new_conf = gh_entry->confidence;
+ new_stride = gh_entry->delta;
+ found = true;
+ globalHistoryRegister.accessEntry(gh_entry);
+ break;
+ }
+ }
+ if (!found) {
+ new_signature = current_block;
+ new_conf = 1.0;
+ new_stride = current_block;
+ }
+}
+
+double
+SignaturePathPrefetcherV2::calculateLookaheadConfidence(
+ PatternEntry const &sig, PatternStrideEntry const &lookahead) const
+{
+ if (sig.counter == 0) return 0.0;
+ return (((double) usefulPrefetches) / issuedPrefetches) *
+ (((double) lookahead.counter) / sig.counter);
+}
+
+double
+SignaturePathPrefetcherV2::calculatePrefetchConfidence(PatternEntry const &sig,
+ PatternStrideEntry const &entry) const
+{
+ if (sig.counter == 0) return 0.0;
+ return ((double) entry.counter) / sig.counter;
+}
+
+void
+SignaturePathPrefetcherV2::increasePatternEntryCounter(
+ PatternEntry &pattern_entry, PatternStrideEntry &pstride_entry)
+{
+ if (pattern_entry.counter == maxCounterValue) {
+ pattern_entry.counter >>= 1;
+ for (auto &entry : pattern_entry.strideEntries) {
+ entry.counter >>= 1;
+ }
+ }
+ if (pstride_entry.counter == maxCounterValue) {
+ pattern_entry.counter >>= 1;
+ for (auto &entry : pattern_entry.strideEntries) {
+ entry.counter >>= 1;
+ }
+ }
+ pattern_entry.counter += 1;
+ pstride_entry.counter += 1;
+}
+
+void
+SignaturePathPrefetcherV2::handlePageCrossingLookahead(signature_t signature,
+ stride_t last_offset, stride_t delta, double path_confidence)
+{
+ // Always use the replacement policy to assign new entries, as all
+ // of them are unique, there are never "hits" in the GHR
+ GlobalHistoryEntry *gh_entry = globalHistoryRegister.findVictim(0);
+ assert(gh_entry != nullptr);
+ // Any address value works, as it is never used
+ globalHistoryRegister.insertEntry(0, false, gh_entry);
+
+ gh_entry->signature = signature;
+ gh_entry->lastBlock = last_offset;
+ gh_entry->delta = delta;
+ gh_entry->confidence = path_confidence;
+}
+
+SignaturePathPrefetcherV2*
+SignaturePathPrefetcherV2Params::create()
+{
+ return new SignaturePathPrefetcherV2(this);
+}
diff --git a/src/mem/cache/prefetch/signature_path_v2.hh b/src/mem/cache/prefetch/signature_path_v2.hh
new file mode 100644
index 000000000..2eed18de9
--- /dev/null
+++ b/src/mem/cache/prefetch/signature_path_v2.hh
@@ -0,0 +1,97 @@
+/**
+ * Copyright (c) 2018 Metempsy Technology Consulting
+ * 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.
+ *
+ * Authors: Javier Bueno
+ */
+
+ /**
+ * Implementation of the Signature Path Prefetcher (v2)
+ *
+ * References:
+ * Path confidence based lookahead prefetching
+ * Jinchun Kim, Seth H. Pugsley, Paul V. Gratz, A. L. Narasimha Reddy,
+ * Chris Wilkerson, and Zeshan Chishti. 2016.
+ * In The 49th Annual IEEE/ACM International Symposium on
+ * Microarchitecture (MICRO-49). IEEE Press, Piscataway, NJ, USA,
+ * Article 60, 12 pages.
+ */
+
+#ifndef __MEM_CACHE_PREFETCH_SIGNATURE_PATH_V2_HH__
+#define __MEM_CACHE_PREFETCH_SIGNATURE_PATH_V2_HH__
+
+#include "mem/cache/prefetch/associative_set.hh"
+#include "mem/cache/prefetch/signature_path.hh"
+#include "mem/packet.hh"
+
+struct SignaturePathPrefetcherV2Params;
+
+class SignaturePathPrefetcherV2 : public SignaturePathPrefetcher
+{
+ /** Global History Register entry datatype */
+ struct GlobalHistoryEntry : public TaggedEntry
+ {
+ signature_t signature;
+ double confidence;
+ stride_t lastBlock;
+ stride_t delta;
+ GlobalHistoryEntry() : signature(0), confidence(0.0), lastBlock(0),
+ delta(0) {}
+ };
+ /** Global History Register */
+ AssociativeSet<GlobalHistoryEntry> globalHistoryRegister;
+
+ double calculateLookaheadConfidence(PatternEntry const &sig,
+ PatternStrideEntry const &lookahead) const override;
+
+ double calculatePrefetchConfidence(PatternEntry const &sig,
+ PatternStrideEntry const &lookahead) const override;
+
+ void increasePatternEntryCounter(PatternEntry &pattern_entry,
+ PatternStrideEntry &pstride_entry) override;
+
+ void handleSignatureTableMiss(stride_t current_block,
+ signature_t &new_signature, double &new_conf,
+ stride_t &new_stride) override;
+
+ /**
+ * In this version of the Signature Path Prefetcher, there is no auxiliary
+ * prefetcher, so this function does not perform any actions.
+ */
+ void auxiliaryPrefetcher(Addr ppn, stride_t current_block, bool is_secure,
+ std::vector<AddrPriority> &addresses) override
+ {}
+
+ virtual void handlePageCrossingLookahead(signature_t signature,
+ stride_t last_offset, stride_t delta, double path_confidence)
+ override;
+
+ public:
+ SignaturePathPrefetcherV2(const SignaturePathPrefetcherV2Params* p);
+ ~SignaturePathPrefetcherV2() {}
+};
+
+#endif//__MEM_CACHE_PREFETCH_SIGNATURE_PATH_V2_HH__