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

Generated on Mon Jan 13 2025 04:28:38 for gem5 by doxygen 1.9.8