gem5 v24.0.0.0
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"
36#include "params/SignaturePathPrefetcher.hh"
37
38namespace gem5
39{
40
41namespace prefetch
42{
43
44SignaturePath::SignaturePath(const SignaturePathPrefetcherParams &p)
45 : Queued(p),
46 stridesPerPatternEntry(p.strides_per_pattern_entry),
47 signatureShift(p.signature_shift),
48 signatureBits(p.signature_bits),
49 prefetchConfidenceThreshold(p.prefetch_confidence_threshold),
50 lookaheadConfidenceThreshold(p.lookahead_confidence_threshold),
51 signatureTable((name() + ".SignatureTable").c_str(),
52 p.signature_table_entries,
53 p.signature_table_assoc,
54 p.signature_table_replacement_policy,
55 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{
64 "The prefetch confidence threshold must be greater than 0\n");
66 "The prefetch confidence threshold must be less than 1\n");
68 "The lookahead confidence threshold must be greater than 0\n");
70 "The lookahead confidence threshold must be less than 1\n");
71}
72
75{
76 PatternStrideEntry *pstride_entry = findStride(stride);
77 if (pstride_entry == nullptr) {
78 // Specific replacement algorithm for this table,
79 // pick the entry with the lowest counter value,
80 // then decrease the counter of all entries
81
82 // If all counters have the max value, this will be the pick
83 PatternStrideEntry *victim_pstride_entry = &(strideEntries[0]);
84
85 unsigned long current_counter = ULONG_MAX;
86 for (auto &entry : strideEntries) {
87 if (entry.counter < current_counter) {
88 victim_pstride_entry = &entry;
89 current_counter = entry.counter;
90 }
91 entry.counter--;
92 }
93 pstride_entry = victim_pstride_entry;
94 pstride_entry->counter.reset();
95 pstride_entry->stride = stride;
96 }
97 return *pstride_entry;
98}
99
100void
102 stride_t delta, double path_confidence, signature_t signature,
103 bool is_secure, std::vector<AddrPriority> &addresses)
104{
105 stride_t block = last_block + delta;
106
107 Addr pf_ppn;
108 stride_t pf_block;
109 if (block < 0) {
110 stride_t num_cross_pages = 1 + (-block) / (pageBytes/blkSize);
111 if (num_cross_pages > ppn) {
112 // target address smaller than page 0, ignore this request;
113 return;
114 }
115 pf_ppn = ppn - num_cross_pages;
116 pf_block = block + (pageBytes/blkSize) * num_cross_pages;
117 handlePageCrossingLookahead(signature, last_block, delta,
118 path_confidence);
119 } else if (block >= (pageBytes/blkSize)) {
120 stride_t num_cross_pages = block / (pageBytes/blkSize);
121 if (MaxAddr/pageBytes < (ppn + num_cross_pages)) {
122 // target address goes beyond MaxAddr, ignore this request;
123 return;
124 }
125 pf_ppn = ppn + num_cross_pages;
126 pf_block = block - (pageBytes/blkSize) * num_cross_pages;
127 handlePageCrossingLookahead(signature, last_block, delta,
128 path_confidence);
129 } else {
130 pf_ppn = ppn;
131 pf_block = block;
132 }
133
134 Addr new_addr = pf_ppn * pageBytes;
135 new_addr += pf_block * (Addr)blkSize;
136
137 DPRINTF(HWPrefetch, "Queuing prefetch to %#x.\n", new_addr);
138 addresses.push_back(AddrPriority(new_addr, 0));
139}
140
141void
143 signature_t &new_signature, double &new_conf, stride_t &new_stride)
144{
145 new_signature = current_block;
146 new_conf = 1.0;
147 new_stride = current_block;
148}
149
150void
152 PatternEntry &pattern_entry, PatternStrideEntry &pstride_entry)
153{
154 pstride_entry.counter++;
155}
156
157void
159{
160 assert(stride != 0);
161 // The pattern table is indexed by signatures
162 PatternEntry &p_entry = getPatternEntry(signature);
163 PatternStrideEntry &ps_entry = p_entry.getStrideEntry(stride);
164 increasePatternEntryCounter(p_entry, ps_entry);
165}
166
169 stride_t block, bool &miss, stride_t &stride,
170 double &initial_confidence)
171{
172 SignatureEntry* signature_entry = signatureTable.findEntry(ppn, is_secure);
173 if (signature_entry != nullptr) {
174 signatureTable.accessEntry(signature_entry);
175 miss = false;
176 stride = block - signature_entry->lastBlock;
177 } else {
178 signature_entry = signatureTable.findVictim(ppn);
179 assert(signature_entry != nullptr);
180
181 // Sets signature_entry->signature, initial_confidence, and stride
182 handleSignatureTableMiss(block, signature_entry->signature,
183 initial_confidence, stride);
184
185 signatureTable.insertEntry(ppn, is_secure, signature_entry);
186 miss = true;
187 }
188 signature_entry->lastBlock = block;
189 return *signature_entry;
190}
191
194{
195 PatternEntry* pattern_entry = patternTable.findEntry(signature);
196 if (pattern_entry != nullptr) {
197 // Signature found
198 patternTable.accessEntry(pattern_entry);
199 } else {
200 // Signature not found
201 pattern_entry = patternTable.findVictim(signature);
202 assert(pattern_entry != nullptr);
203
204 patternTable.insertEntry(signature, pattern_entry);
205 }
206 return *pattern_entry;
207}
208
209double
211 PatternStrideEntry const &entry) const
212{
213 return entry.counter.calcSaturation();
214}
215
216double
218 PatternStrideEntry const &lookahead) const
219{
220 double lookahead_confidence = lookahead.counter.calcSaturation();
221 if (lookahead_confidence > 0.95) {
227 lookahead_confidence = 0.95;
228 }
229 return lookahead_confidence;
230}
231
232void
234 std::vector<AddrPriority> &addresses,
235 const CacheAccessor &cache)
236{
237 Addr request_addr = pfi.getAddr();
238 Addr ppn = request_addr / pageBytes;
239 stride_t current_block = (request_addr % pageBytes) / blkSize;
241 bool is_secure = pfi.isSecure();
242 double initial_confidence = 1.0;
243
244 // Get the SignatureEntry of this page to:
245 // - compute the current stride
246 // - obtain the current signature of accesses
247 bool miss;
248 SignatureEntry &signature_entry = getSignatureEntry(ppn, is_secure,
249 current_block, miss, stride, initial_confidence);
250
251 if (miss) {
252 // No history for this page, can't continue
253 return;
254 }
255
256 if (stride == 0) {
257 // Can't continue with a stride 0
258 return;
259 }
260
261 // Update the confidence of the current signature
262 updatePatternTable(signature_entry.signature, stride);
263
264 // Update the current SignatureEntry signature
265 signature_entry.signature =
266 updateSignature(signature_entry.signature, stride);
267
268 signature_t current_signature = signature_entry.signature;
269 double current_confidence = initial_confidence;
270 stride_t current_stride = signature_entry.lastBlock;
271
272 // Look for prefetch candidates while the current path confidence is
273 // high enough
274 while (current_confidence > lookaheadConfidenceThreshold) {
275 // With the updated signature, attempt to generate prefetches
276 // - search the PatternTable and select all entries with enough
277 // confidence, these are prefetch candidates
278 // - select the entry with the highest counter as the "lookahead"
279 PatternEntry *current_pattern_entry =
280 patternTable.findEntry(current_signature);
281 PatternStrideEntry const *lookahead = nullptr;
282 if (current_pattern_entry != nullptr) {
283 unsigned long max_counter = 0;
284 for (auto const &entry : current_pattern_entry->strideEntries) {
285 //select the entry with the maximum counter value as lookahead
286 if (max_counter < entry.counter) {
287 max_counter = entry.counter;
288 lookahead = &entry;
289 }
290 double prefetch_confidence =
291 calculatePrefetchConfidence(*current_pattern_entry, entry);
292
293 if (prefetch_confidence >= prefetchConfidenceThreshold) {
294 assert(entry.stride != 0);
295 //prefetch candidate
296 addPrefetch(ppn, current_stride, entry.stride,
297 current_confidence, current_signature,
298 is_secure, addresses);
299 }
300 }
301 }
302
303 if (lookahead != nullptr) {
304 current_confidence *= calculateLookaheadConfidence(
305 *current_pattern_entry, *lookahead);
306 current_signature =
307 updateSignature(current_signature, lookahead->stride);
308 current_stride += lookahead->stride;
309 } else {
310 current_confidence = 0.0;
311 }
312 }
313
314 auxiliaryPrefetcher(ppn, current_block, is_secure, addresses);
315}
316
317void
319 bool is_secure, std::vector<AddrPriority> &addresses)
320{
321 if (addresses.empty()) {
322 // Enable the next line prefetcher if no prefetch candidates are found
323 addPrefetch(ppn, current_block, 1, 0.0 /* unused*/, 0 /* unused */,
324 is_secure, addresses);
325 }
326}
327
328} // namespace prefetch
329} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:210
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.
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.
AssociativeSet< SignatureEntry > signatureTable
Signature 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 - Pranith Kumar Copyright (c) 2020 Inria 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
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 Tue Jun 18 2024 16:24:05 for gem5 by doxygen 1.11.0