summaryrefslogtreecommitdiff
path: root/src/mem/cache/prefetch/signature_path.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem/cache/prefetch/signature_path.cc')
-rw-r--r--src/mem/cache/prefetch/signature_path.cc153
1 files changed, 105 insertions, 48 deletions
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);
}
}