gem5 v23.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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(p.signature_table_assoc, p.signature_table_entries,
52 p.signature_table_indexing_policy,
53 p.signature_table_replacement_policy),
54 patternTable(p.pattern_table_assoc, p.pattern_table_entries,
55 p.pattern_table_indexing_policy,
56 p.pattern_table_replacement_policy,
57 PatternEntry(stridesPerPatternEntry, p.num_counter_bits))
58{
60 "The prefetch confidence threshold must be greater than 0\n");
62 "The prefetch confidence threshold must be less than 1\n");
64 "The lookahead confidence threshold must be greater than 0\n");
66 "The lookahead confidence threshold must be less than 1\n");
67}
68
71{
72 PatternStrideEntry *pstride_entry = findStride(stride);
73 if (pstride_entry == nullptr) {
74 // Specific replacement algorithm for this table,
75 // pick the entry with the lowest counter value,
76 // then decrease the counter of all entries
77
78 // If all counters have the max value, this will be the pick
79 PatternStrideEntry *victim_pstride_entry = &(strideEntries[0]);
80
81 unsigned long current_counter = ULONG_MAX;
82 for (auto &entry : strideEntries) {
83 if (entry.counter < current_counter) {
84 victim_pstride_entry = &entry;
85 current_counter = entry.counter;
86 }
87 entry.counter--;
88 }
89 pstride_entry = victim_pstride_entry;
90 pstride_entry->counter.reset();
91 pstride_entry->stride = stride;
92 }
93 return *pstride_entry;
94}
95
96void
98 stride_t delta, double path_confidence, signature_t signature,
99 bool is_secure, std::vector<AddrPriority> &addresses)
100{
101 stride_t block = last_block + delta;
102
103 Addr pf_ppn;
104 stride_t pf_block;
105 if (block < 0) {
106 stride_t num_cross_pages = 1 + (-block) / (pageBytes/blkSize);
107 if (num_cross_pages > ppn) {
108 // target address smaller than page 0, ignore this request;
109 return;
110 }
111 pf_ppn = ppn - num_cross_pages;
112 pf_block = block + (pageBytes/blkSize) * num_cross_pages;
113 handlePageCrossingLookahead(signature, last_block, delta,
114 path_confidence);
115 } else if (block >= (pageBytes/blkSize)) {
116 stride_t num_cross_pages = block / (pageBytes/blkSize);
117 if (MaxAddr/pageBytes < (ppn + num_cross_pages)) {
118 // target address goes beyond MaxAddr, ignore this request;
119 return;
120 }
121 pf_ppn = ppn + num_cross_pages;
122 pf_block = block - (pageBytes/blkSize) * num_cross_pages;
123 handlePageCrossingLookahead(signature, last_block, delta,
124 path_confidence);
125 } else {
126 pf_ppn = ppn;
127 pf_block = block;
128 }
129
130 Addr new_addr = pf_ppn * pageBytes;
131 new_addr += pf_block * (Addr)blkSize;
132
133 DPRINTF(HWPrefetch, "Queuing prefetch to %#x.\n", new_addr);
134 addresses.push_back(AddrPriority(new_addr, 0));
135}
136
137void
139 signature_t &new_signature, double &new_conf, stride_t &new_stride)
140{
141 new_signature = current_block;
142 new_conf = 1.0;
143 new_stride = current_block;
144}
145
146void
148 PatternEntry &pattern_entry, PatternStrideEntry &pstride_entry)
149{
150 pstride_entry.counter++;
151}
152
153void
155{
156 assert(stride != 0);
157 // The pattern table is indexed by signatures
158 PatternEntry &p_entry = getPatternEntry(signature);
159 PatternStrideEntry &ps_entry = p_entry.getStrideEntry(stride);
160 increasePatternEntryCounter(p_entry, ps_entry);
161}
162
165 stride_t block, bool &miss, stride_t &stride,
166 double &initial_confidence)
167{
168 SignatureEntry* signature_entry = signatureTable.findEntry(ppn, is_secure);
169 if (signature_entry != nullptr) {
170 signatureTable.accessEntry(signature_entry);
171 miss = false;
172 stride = block - signature_entry->lastBlock;
173 } else {
174 signature_entry = signatureTable.findVictim(ppn);
175 assert(signature_entry != nullptr);
176
177 // Sets signature_entry->signature, initial_confidence, and stride
178 handleSignatureTableMiss(block, signature_entry->signature,
179 initial_confidence, stride);
180
181 signatureTable.insertEntry(ppn, is_secure, signature_entry);
182 miss = true;
183 }
184 signature_entry->lastBlock = block;
185 return *signature_entry;
186}
187
190{
191 PatternEntry* pattern_entry = patternTable.findEntry(signature, false);
192 if (pattern_entry != nullptr) {
193 // Signature found
194 patternTable.accessEntry(pattern_entry);
195 } else {
196 // Signature not found
197 pattern_entry = patternTable.findVictim(signature);
198 assert(pattern_entry != nullptr);
199
200 patternTable.insertEntry(signature, false, pattern_entry);
201 }
202 return *pattern_entry;
203}
204
205double
207 PatternStrideEntry const &entry) const
208{
209 return entry.counter.calcSaturation();
210}
211
212double
214 PatternStrideEntry const &lookahead) const
215{
216 double lookahead_confidence = lookahead.counter.calcSaturation();
217 if (lookahead_confidence > 0.95) {
223 lookahead_confidence = 0.95;
224 }
225 return lookahead_confidence;
226}
227
228void
230 std::vector<AddrPriority> &addresses)
231{
232 Addr request_addr = pfi.getAddr();
233 Addr ppn = request_addr / pageBytes;
234 stride_t current_block = (request_addr % pageBytes) / blkSize;
236 bool is_secure = pfi.isSecure();
237 double initial_confidence = 1.0;
238
239 // Get the SignatureEntry of this page to:
240 // - compute the current stride
241 // - obtain the current signature of accesses
242 bool miss;
243 SignatureEntry &signature_entry = getSignatureEntry(ppn, is_secure,
244 current_block, miss, stride, initial_confidence);
245
246 if (miss) {
247 // No history for this page, can't continue
248 return;
249 }
250
251 if (stride == 0) {
252 // Can't continue with a stride 0
253 return;
254 }
255
256 // Update the confidence of the current signature
257 updatePatternTable(signature_entry.signature, stride);
258
259 // Update the current SignatureEntry signature
260 signature_entry.signature =
261 updateSignature(signature_entry.signature, stride);
262
263 signature_t current_signature = signature_entry.signature;
264 double current_confidence = initial_confidence;
265 stride_t current_stride = signature_entry.lastBlock;
266
267 // Look for prefetch candidates while the current path confidence is
268 // high enough
269 while (current_confidence > lookaheadConfidenceThreshold) {
270 // With the updated signature, attempt to generate prefetches
271 // - search the PatternTable and select all entries with enough
272 // confidence, these are prefetch candidates
273 // - select the entry with the highest counter as the "lookahead"
274 PatternEntry *current_pattern_entry =
275 patternTable.findEntry(current_signature, false);
276 PatternStrideEntry const *lookahead = nullptr;
277 if (current_pattern_entry != nullptr) {
278 unsigned long max_counter = 0;
279 for (auto const &entry : current_pattern_entry->strideEntries) {
280 //select the entry with the maximum counter value as lookahead
281 if (max_counter < entry.counter) {
282 max_counter = entry.counter;
283 lookahead = &entry;
284 }
285 double prefetch_confidence =
286 calculatePrefetchConfidence(*current_pattern_entry, entry);
287
288 if (prefetch_confidence >= prefetchConfidenceThreshold) {
289 assert(entry.stride != 0);
290 //prefetch candidate
291 addPrefetch(ppn, current_stride, entry.stride,
292 current_confidence, current_signature,
293 is_secure, addresses);
294 }
295 }
296 }
297
298 if (lookahead != nullptr) {
299 current_confidence *= calculateLookaheadConfidence(
300 *current_pattern_entry, *lookahead);
301 current_signature =
302 updateSignature(current_signature, lookahead->stride);
303 current_stride += lookahead->stride;
304 } else {
305 current_confidence = 0.0;
306 }
307 }
308
309 auxiliaryPrefetcher(ppn, current_block, is_secure, addresses);
310}
311
312void
314 bool is_secure, std::vector<AddrPriority> &addresses)
315{
316 if (addresses.empty()) {
317 // Enable the next line prefetcher if no prefetch candidates are found
318 addPrefetch(ppn, current_block, 1, 0.0 /* unused*/, 0 /* unused */,
319 is_secure, addresses);
320 }
321}
322
323} // namespace prefetch
324} // 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:97
bool isSecure() const
Returns true if the address targets the secure memory space.
Definition base.hh:133
Addr getAddr() const
Obtains the address value of this Prefetcher address.
Definition base.hh:124
unsigned blkSize
The block size of the parent cache.
Definition base.hh:269
const Addr pageBytes
Definition base.hh:292
std::pair< Addr, int32_t > AddrPriority
Definition queued.hh:190
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.
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...
AssociativeSet< PatternEntry > patternTable
Pattern table.
void calculatePrefetch(const PrefetchInfo &pfi, std::vector< AddrPriority > &addresses) override
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
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
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
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.

Generated on Mon Jul 10 2023 14:24:32 for gem5 by doxygen 1.9.7