gem5  v20.1.0.0
signature_path.cc
Go to the documentation of this file.
1 
30 
31 #include <cassert>
32 #include <climits>
33 
34 #include "debug/HWPrefetch.hh"
36 #include "params/SignaturePathPrefetcher.hh"
37 
38 namespace Prefetcher {
39 
40 SignaturePath::SignaturePath(const SignaturePathPrefetcherParams *p)
41  : Queued(p),
42  stridesPerPatternEntry(p->strides_per_pattern_entry),
43  signatureShift(p->signature_shift),
44  signatureBits(p->signature_bits),
45  prefetchConfidenceThreshold(p->prefetch_confidence_threshold),
46  lookaheadConfidenceThreshold(p->lookahead_confidence_threshold),
47  signatureTable(p->signature_table_assoc, p->signature_table_entries,
48  p->signature_table_indexing_policy,
49  p->signature_table_replacement_policy),
50  patternTable(p->pattern_table_assoc, p->pattern_table_entries,
51  p->pattern_table_indexing_policy,
52  p->pattern_table_replacement_policy,
53  PatternEntry(stridesPerPatternEntry, p->num_counter_bits))
54 {
56  "The prefetch confidence threshold must be greater than 0\n");
58  "The prefetch confidence threshold must be less than 1\n");
60  "The lookahead confidence threshold must be greater than 0\n");
62  "The lookahead confidence threshold must be less than 1\n");
63 }
64 
67 {
68  PatternStrideEntry *pstride_entry = findStride(stride);
69  if (pstride_entry == nullptr) {
70  // Specific replacement algorithm for this table,
71  // pick the entry with the lowest counter value,
72  // then decrease the counter of all entries
73 
74  // If all counters have the max value, this will be the pick
75  PatternStrideEntry *victim_pstride_entry = &(strideEntries[0]);
76 
77  unsigned long current_counter = ULONG_MAX;
78  for (auto &entry : strideEntries) {
79  if (entry.counter < current_counter) {
80  victim_pstride_entry = &entry;
81  current_counter = entry.counter;
82  }
83  entry.counter--;
84  }
85  pstride_entry = victim_pstride_entry;
86  pstride_entry->counter.reset();
87  pstride_entry->stride = stride;
88  }
89  return *pstride_entry;
90 }
91 
92 void
94  stride_t delta, double path_confidence, signature_t signature,
95  bool is_secure, std::vector<AddrPriority> &addresses)
96 {
97  stride_t block = last_block + delta;
98 
99  Addr pf_ppn;
100  stride_t pf_block;
101  if (block < 0) {
102  stride_t num_cross_pages = 1 + (-block) / (pageBytes/blkSize);
103  if (num_cross_pages > ppn) {
104  // target address smaller than page 0, ignore this request;
105  return;
106  }
107  pf_ppn = ppn - num_cross_pages;
108  pf_block = block + (pageBytes/blkSize) * num_cross_pages;
109  handlePageCrossingLookahead(signature, last_block, delta,
110  path_confidence);
111  } else if (block >= (pageBytes/blkSize)) {
112  stride_t num_cross_pages = block / (pageBytes/blkSize);
113  if (MaxAddr/pageBytes < (ppn + num_cross_pages)) {
114  // target address goes beyond MaxAddr, ignore this request;
115  return;
116  }
117  pf_ppn = ppn + num_cross_pages;
118  pf_block = block - (pageBytes/blkSize) * num_cross_pages;
119  handlePageCrossingLookahead(signature, last_block, delta,
120  path_confidence);
121  } else {
122  pf_ppn = ppn;
123  pf_block = block;
124  }
125 
126  Addr new_addr = pf_ppn * pageBytes;
127  new_addr += pf_block * (Addr)blkSize;
128 
129  DPRINTF(HWPrefetch, "Queuing prefetch to %#x.\n", new_addr);
130  addresses.push_back(AddrPriority(new_addr, 0));
131 }
132 
133 void
135  signature_t &new_signature, double &new_conf, stride_t &new_stride)
136 {
137  new_signature = current_block;
138  new_conf = 1.0;
139  new_stride = current_block;
140 }
141 
142 void
144  PatternEntry &pattern_entry, PatternStrideEntry &pstride_entry)
145 {
146  pstride_entry.counter++;
147 }
148 
149 void
151 {
152  assert(stride != 0);
153  // The pattern table is indexed by signatures
154  PatternEntry &p_entry = getPatternEntry(signature);
155  PatternStrideEntry &ps_entry = p_entry.getStrideEntry(stride);
156  increasePatternEntryCounter(p_entry, ps_entry);
157 }
158 
161  stride_t block, bool &miss, stride_t &stride,
162  double &initial_confidence)
163 {
164  SignatureEntry* signature_entry = signatureTable.findEntry(ppn, is_secure);
165  if (signature_entry != nullptr) {
166  signatureTable.accessEntry(signature_entry);
167  miss = false;
168  stride = block - signature_entry->lastBlock;
169  } else {
170  signature_entry = signatureTable.findVictim(ppn);
171  assert(signature_entry != nullptr);
172 
173  // Sets signature_entry->signature, initial_confidence, and stride
174  handleSignatureTableMiss(block, signature_entry->signature,
175  initial_confidence, stride);
176 
177  signatureTable.insertEntry(ppn, is_secure, signature_entry);
178  miss = true;
179  }
180  signature_entry->lastBlock = block;
181  return *signature_entry;
182 }
183 
186 {
187  PatternEntry* pattern_entry = patternTable.findEntry(signature, false);
188  if (pattern_entry != nullptr) {
189  // Signature found
190  patternTable.accessEntry(pattern_entry);
191  } else {
192  // Signature not found
193  pattern_entry = patternTable.findVictim(signature);
194  assert(pattern_entry != nullptr);
195 
196  patternTable.insertEntry(signature, false, pattern_entry);
197  }
198  return *pattern_entry;
199 }
200 
201 double
203  PatternStrideEntry const &entry) const
204 {
205  return entry.counter.calcSaturation();
206 }
207 
208 double
210  PatternStrideEntry const &lookahead) const
211 {
212  double lookahead_confidence = lookahead.counter.calcSaturation();
213  if (lookahead_confidence > 0.95) {
219  lookahead_confidence = 0.95;
220  }
221  return lookahead_confidence;
222 }
223 
224 void
226  std::vector<AddrPriority> &addresses)
227 {
228  Addr request_addr = pfi.getAddr();
229  Addr ppn = request_addr / pageBytes;
230  stride_t current_block = (request_addr % pageBytes) / blkSize;
232  bool is_secure = pfi.isSecure();
233  double initial_confidence = 1.0;
234 
235  // Get the SignatureEntry of this page to:
236  // - compute the current stride
237  // - obtain the current signature of accesses
238  bool miss;
239  SignatureEntry &signature_entry = getSignatureEntry(ppn, is_secure,
240  current_block, miss, stride, initial_confidence);
241 
242  if (miss) {
243  // No history for this page, can't continue
244  return;
245  }
246 
247  if (stride == 0) {
248  // Can't continue with a stride 0
249  return;
250  }
251 
252  // Update the confidence of the current signature
253  updatePatternTable(signature_entry.signature, stride);
254 
255  // Update the current SignatureEntry signature
256  signature_entry.signature =
257  updateSignature(signature_entry.signature, stride);
258 
259  signature_t current_signature = signature_entry.signature;
260  double current_confidence = initial_confidence;
261  stride_t current_stride = signature_entry.lastBlock;
262 
263  // Look for prefetch candidates while the current path confidence is
264  // high enough
265  while (current_confidence > lookaheadConfidenceThreshold) {
266  // With the updated signature, attempt to generate prefetches
267  // - search the PatternTable and select all entries with enough
268  // confidence, these are prefetch candidates
269  // - select the entry with the highest counter as the "lookahead"
270  PatternEntry *current_pattern_entry =
271  patternTable.findEntry(current_signature, false);
272  PatternStrideEntry const *lookahead = nullptr;
273  if (current_pattern_entry != nullptr) {
274  unsigned long max_counter = 0;
275  for (auto const &entry : current_pattern_entry->strideEntries) {
276  //select the entry with the maximum counter value as lookahead
277  if (max_counter < entry.counter) {
278  max_counter = entry.counter;
279  lookahead = &entry;
280  }
281  double prefetch_confidence =
282  calculatePrefetchConfidence(*current_pattern_entry, entry);
283 
284  if (prefetch_confidence >= prefetchConfidenceThreshold) {
285  assert(entry.stride != 0);
286  //prefetch candidate
287  addPrefetch(ppn, current_stride, entry.stride,
288  current_confidence, current_signature,
289  is_secure, addresses);
290  }
291  }
292  }
293 
294  if (lookahead != nullptr) {
295  current_confidence *= calculateLookaheadConfidence(
296  *current_pattern_entry, *lookahead);
297  current_signature =
298  updateSignature(current_signature, lookahead->stride);
299  current_stride += lookahead->stride;
300  } else {
301  current_confidence = 0.0;
302  }
303  }
304 
305  auxiliaryPrefetcher(ppn, current_block, is_secure, addresses);
306 }
307 
308 void
310  bool is_secure, std::vector<AddrPriority> &addresses)
311 {
312  if (addresses.empty()) {
313  // Enable the next line prefetcher if no prefetch candidates are found
314  addPrefetch(ppn, current_block, 1, 0.0 /* unused*/, 0 /* unused */,
315  is_secure, addresses);
316  }
317 }
318 
319 } // namespace Prefetcher
320 
322 SignaturePathPrefetcherParams::create()
323 {
324  return new Prefetcher::SignaturePath(this);
325 }
associative_set_impl.hh
Prefetcher::SignaturePath::SignatureEntry::lastBlock
stride_t lastBlock
Last accessed block within a page.
Definition: signature_path.hh:77
Prefetcher::Queued::AddrPriority
std::pair< Addr, int32_t > AddrPriority
Definition: queued.hh:182
Prefetcher::SignaturePath::getPatternEntry
PatternEntry & getPatternEntry(Addr signature)
Obtains the PatternEntry of the given signature, if the signature is not found, it allocates a new on...
Definition: signature_path.cc:185
SatCounter::reset
void reset()
Reset the counter to its initial value.
Definition: sat_counter.hh:286
Prefetcher::SignaturePath::increasePatternEntryCounter
virtual void increasePatternEntryCounter(PatternEntry &pattern_entry, PatternStrideEntry &pstride_entry)
Increases the counter of a given PatternEntry/PatternStrideEntry.
Definition: signature_path.cc:143
Prefetcher::SignaturePath::PatternStrideEntry
A stride entry with its counter.
Definition: signature_path.hh:85
Prefetcher::Base::blkSize
unsigned blkSize
The block size of the parent cache.
Definition: base.hh:262
RiscvISA::ppn
Bitfield< 43, 0 > ppn
Definition: pagetable.hh:44
Prefetcher::SignaturePath::patternTable
AssociativeSet< PatternEntry > patternTable
Pattern table.
Definition: signature_path.hh:146
Prefetcher::SignaturePath::PatternEntry::getStrideEntry
PatternStrideEntry & getStrideEntry(stride_t stride)
Gets the entry with the provided stride, if there is no entry with the associated stride,...
Definition: signature_path.cc:66
Prefetcher::SignaturePath::calculateLookaheadConfidence
virtual double calculateLookaheadConfidence(PatternEntry const &sig, PatternStrideEntry const &lookahead) const
Computes the lookahead path confidence of the provided pattern entry.
Definition: signature_path.cc:209
Prefetcher::SignaturePath::calculatePrefetch
void calculatePrefetch(const PrefetchInfo &pfi, std::vector< AddrPriority > &addresses) override
Definition: signature_path.cc:225
std::vector
STL vector class.
Definition: stl.hh:37
Prefetcher::SignaturePath::PatternStrideEntry::stride
stride_t stride
stride in a page in blkSize increments
Definition: signature_path.hh:88
MaxAddr
const Addr MaxAddr
Definition: types.hh:166
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:234
SatCounter::calcSaturation
double calcSaturation() const
Calculate saturation percentile of the current counter's value with regard to its maximum possible va...
Definition: sat_counter.hh:297
Prefetcher::SignaturePath::stride_t
int16_t stride_t
Stride type.
Definition: signature_path.hh:58
Prefetcher::SignaturePath::SignatureEntry::signature
signature_t signature
Path signature.
Definition: signature_path.hh:75
Prefetcher::SignaturePath::lookaheadConfidenceThreshold
const double lookaheadConfidenceThreshold
Minimum confidence to keep navigating lookahead entries.
Definition: signature_path.hh:69
Prefetcher::SignaturePath::updateSignature
signature_t updateSignature(signature_t sig, stride_t str) const
Generates a new signature from an existing one and a new stride.
Definition: signature_path.hh:154
Prefetcher::SignaturePath::PatternEntry
Pattern entry data type, a set of stride and counter entries.
Definition: signature_path.hh:95
Prefetcher::SignaturePath::PatternStrideEntry::counter
SatCounter counter
Saturating counter.
Definition: signature_path.hh:90
Prefetcher
Copyright (c) 2018 Metempsy Technology Consulting All rights reserved.
Definition: base.hh:78
Prefetcher::SignaturePath::calculatePrefetchConfidence
virtual double calculatePrefetchConfidence(PatternEntry const &sig, PatternStrideEntry const &entry) const
Computes the prefetch confidence of the provided pattern entry.
Definition: signature_path.cc:202
Prefetcher::SignaturePath::signatureTable
AssociativeSet< SignatureEntry > signatureTable
Signature table.
Definition: signature_path.hh:82
Prefetcher::SignaturePath::PatternEntry::strideEntries
std::vector< PatternStrideEntry > strideEntries
group of stides
Definition: signature_path.hh:98
Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
Prefetcher::Queued
Definition: queued.hh:54
Prefetcher::Base::PrefetchInfo::isSecure
bool isSecure() const
Returns true if the address targets the secure memory space.
Definition: base.hh:126
SatCounter::counter
uint8_t counter
Definition: sat_counter.hh:325
Prefetcher::SignaturePath::updatePatternTable
void updatePatternTable(Addr signature, stride_t stride)
Updates the pattern table with the provided signature and stride.
Definition: signature_path.cc:150
Prefetcher::SignaturePath
Definition: signature_path.hh:52
Prefetcher::SignaturePath::signature_t
uint16_t signature_t
Signature type.
Definition: signature_path.hh:56
Prefetcher::Base::PrefetchInfo
Class containing the information needed by the prefetch to train and generate new prefetch requests.
Definition: base.hh:90
ArmISA::stride
Bitfield< 21, 20 > stride
Definition: miscregs_types.hh:441
Prefetcher::SignaturePath::prefetchConfidenceThreshold
const double prefetchConfidenceThreshold
Minimum confidence to issue a prefetch.
Definition: signature_path.hh:67
Prefetcher::SignaturePath::auxiliaryPrefetcher
virtual void auxiliaryPrefetcher(Addr ppn, stride_t current_block, bool is_secure, std::vector< AddrPriority > &addresses)
Auxiliar prefetch mechanism used at the end of calculatePrefetch.
Definition: signature_path.cc:309
Prefetcher::SignaturePath::getSignatureEntry
SignatureEntry & getSignatureEntry(Addr ppn, bool is_secure, stride_t block, bool &miss, stride_t &stride, double &initial_confidence)
Obtains the SignatureEntry of the given page, if the page is not found, it allocates a new one,...
Definition: signature_path.cc:160
MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:323
Prefetcher::SignaturePath::addPrefetch
void addPrefetch(Addr ppn, stride_t last_block, stride_t delta, double path_confidence, signature_t signature, bool is_secure, std::vector< AddrPriority > &addresses)
Generates an address to be prefetched.
Definition: signature_path.cc:93
Prefetcher::Base::pageBytes
const Addr pageBytes
Definition: base.hh:285
fatal_if
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition: logging.hh:219
Prefetcher::SignaturePath::handlePageCrossingLookahead
virtual void handlePageCrossingLookahead(signature_t signature, stride_t last_offset, stride_t delta, double path_confidence)
Handles the situation when the lookahead process has crossed the boundaries of the current page.
Definition: signature_path.hh:277
Prefetcher::SignaturePath::SignaturePath
SignaturePath(const SignaturePathPrefetcherParams *p)
Definition: signature_path.cc:40
signature_path.hh
Prefetcher::Base::PrefetchInfo::getAddr
Addr getAddr() const
Obtains the address value of this Prefetcher address.
Definition: base.hh:117
Prefetcher::SignaturePath::PatternEntry::findStride
PatternStrideEntry * findStride(stride_t stride)
Returns the entry with the desired stride.
Definition: signature_path.hh:125
Prefetcher::SignaturePath::handleSignatureTableMiss
virtual void handleSignatureTableMiss(stride_t current_block, signature_t &new_signature, double &new_conf, stride_t &new_stride)
Whenever a new SignatureEntry is allocated, it computes the new signature to be used with the new ent...
Definition: signature_path.cc:134
Prefetcher::SignaturePath::SignatureEntry
Signature entry data type.
Definition: signature_path.hh:72

Generated on Wed Sep 30 2020 14:02:12 for gem5 by doxygen 1.8.17