gem5 v24.1.0.1
Loading...
Searching...
No Matches
spatio_temporal_memory_streaming.cc
Go to the documentation of this file.
1
30
31#include "debug/HWPrefetch.hh"
32#include "params/STeMSPrefetcher.hh"
33
34namespace gem5
35{
36
37namespace prefetch
38{
39
40STeMS::STeMS(const STeMSPrefetcherParams &p)
41 : Queued(p), spatialRegionSize(p.spatial_region_size),
42 spatialRegionSizeBits(floorLog2(p.spatial_region_size)),
43 reconstructionEntries(p.reconstruction_entries),
44 activeGenerationTable((name() + ".ActiveGenerationTable").c_str(),
45 p.active_generation_table_entries,
46 p.active_generation_table_assoc,
47 p.active_generation_table_replacement_policy,
48 p.active_generation_table_indexing_policy,
50 spatialRegionSize / blkSize,
51 genTagExtractor(p.active_generation_table_indexing_policy))),
52 patternSequenceTable((name() + ".PatternSequenceTable").c_str(),
53 p.pattern_sequence_table_entries,
54 p.pattern_sequence_table_assoc,
55 p.pattern_sequence_table_replacement_policy,
56 p.pattern_sequence_table_indexing_policy,
58 spatialRegionSize / blkSize,
59 genTagExtractor(p.pattern_sequence_table_indexing_policy))),
60 rmob(p.region_miss_order_buffer_entries),
61 addDuplicateEntriesToRMOB(p.add_duplicate_entries_to_rmob),
62 lastTriggerCounter(0)
63{
65 "The spatial region size must be a power of 2.");
66}
67
68void
70{
71 // This prefetcher operates attached to the L1 and it observes all
72 // accesses, this guarantees that no evictions are missed
73
74 // Iterate over all entries, if any recorded cacheline has been evicted,
75 // the generation finishes, move the entry to the PST
76 for (auto &agt_entry : activeGenerationTable) {
77 if (agt_entry.isValid()) {
78 bool generation_ended = false;
79 bool sr_is_secure = agt_entry.isSecure();
80 Addr pst_addr = 0;
81 for (auto &seq_entry : agt_entry.sequence) {
82 if (seq_entry.counter > 0) {
83 Addr cache_addr =
84 agt_entry.paddress + seq_entry.offset * blkSize;
85 if (!cache.inCache(cache_addr, sr_is_secure) &&
86 !cache.inMissQueue(cache_addr, sr_is_secure)) {
87 generation_ended = true;
88 pst_addr = (agt_entry.pc << spatialRegionSizeBits)
89 + seq_entry.offset;
90 break;
91 }
92 }
93 }
94 if (generation_ended) {
95 const ActiveGenerationTableEntry::KeyType key{pst_addr, false};
96 // PST is indexed using the PC (secure bit is unused)
97 auto pst_entry = patternSequenceTable.findEntry(key);
98 if (pst_entry == nullptr) {
99 // Tipically an entry will not exist
100 pst_entry = patternSequenceTable.findVictim(key);
101 assert(pst_entry != nullptr);
102 patternSequenceTable.insertEntry(key, pst_entry);
103 } else {
104 patternSequenceTable.accessEntry(pst_entry);
105 }
106 // If the entry existed, this will update the values, if not,
107 // this also sets the values of the entry
108 pst_entry->update(agt_entry);
109 // Free the AGT entry
110 activeGenerationTable.invalidate(&agt_entry);
111 }
112 }
113 }
114}
115
116void
117STeMS::addToRMOB(Addr sr_addr, Addr pst_addr, unsigned int delta)
118{
120 rmob_entry.srAddress = sr_addr;
121 rmob_entry.pstAddress = pst_addr;
122 rmob_entry.delta = delta;
123
125 for (const auto& entry : rmob) {
126 if (entry.srAddress == sr_addr &&
127 entry.pstAddress == pst_addr &&
128 entry.delta == delta) {
129 return;
130 }
131 }
132 }
133
134 rmob.push_back(rmob_entry);
135}
136
137void
139 std::vector<AddrPriority> &addresses,
140 const CacheAccessor &cache)
141{
142 if (!pfi.hasPC()) {
143 DPRINTF(HWPrefetch, "Ignoring request with no PC.\n");
144 return;
145 }
146
147 Addr pc = pfi.getPC();
148 bool is_secure = pfi.isSecure();
149 // Spatial region address
150 Addr sr_addr = pfi.getAddr() / spatialRegionSize;
151 Addr paddr = pfi.getPaddr();
152
153 // Offset in cachelines within the spatial region
154 Addr sr_offset = (pfi.getAddr() % spatialRegionSize) / blkSize;
155
156 // Check if any active generation has ended
158
159 const ActiveGenerationTableEntry::KeyType key{sr_addr, is_secure};
160 ActiveGenerationTableEntry *agt_entry =
161 activeGenerationTable.findEntry(key);
162 if (agt_entry != nullptr) {
163 // found an entry in the AGT, entry is currently being recorded,
164 // add the offset
165 activeGenerationTable.accessEntry(agt_entry);
166 agt_entry->addOffset(sr_offset);
168 } else {
169 // Not found, this is the first access (Trigger access)
170
171 // Add entry to RMOB
172 Addr pst_addr = (pc << spatialRegionSizeBits) + sr_offset;
173 addToRMOB(sr_addr, pst_addr, lastTriggerCounter);
174 // Reset last trigger counter
176
177 // allocate a new AGT entry
178 agt_entry = activeGenerationTable.findVictim(key);
179 assert(agt_entry != nullptr);
180 activeGenerationTable.insertEntry(key, agt_entry);
181 agt_entry->pc = pc;
182 agt_entry->paddress = paddr;
183 agt_entry->addOffset(sr_offset);
184 }
185 // increase the seq Counter for other entries
186 for (auto &agt_e : activeGenerationTable) {
187 if (agt_e.isValid() && agt_entry != &agt_e) {
188 agt_e.seqCounter += 1;
189 }
190 }
191
192 // Prefetch generation: if this is a miss, search for the most recent
193 // entry in the RMOB, and reconstruct the registered access sequence
194 if (pfi.isCacheMiss()) {
195 auto it = rmob.end();
196 while (it != rmob.begin()) {
197 --it;
198 if (it->srAddress == sr_addr) {
199 // reconstruct the access sequence
200 reconstructSequence(it, addresses);
201 break;
202 }
203 }
204 }
205}
206
207void
210 std::vector<AddrPriority> &addresses)
211{
213 unsigned int idx = 0;
214
215 // Process rmob entries from rmob_it (most recent with address = sr_addr)
216 // to the latest one
217 for (auto it = rmob_it; it != rmob.end() && (idx < reconstructionEntries);
218 it++) {
219 reconstruction[idx] = it->srAddress * spatialRegionSize;
220 idx += (it+1)->delta + 1;
221 }
222
223 // Now query the PST with the PC of each RMOB entry
224 idx = 0;
225 for (auto it = rmob_it; it != rmob.end() && (idx < reconstructionEntries);
226 it++) {
227 auto pst_entry = patternSequenceTable.findEntry(
228 {it->pstAddress, false});
229 if (pst_entry != nullptr) {
230 patternSequenceTable.accessEntry(pst_entry);
231 for (auto &seq_entry : pst_entry->sequence) {
232 if (seq_entry.counter > 1) {
233 // 2-bit counter: high enough confidence with a
234 // value greater than 1
235 Addr rec_addr = it->srAddress * spatialRegionSize +
236 seq_entry.offset;
237 unsigned ridx = idx + seq_entry.delta;
238 // Try to use the corresponding position, if it has been
239 // already used, look the surrounding positions
240 if (ridx < reconstructionEntries &&
241 reconstruction[ridx] == MaxAddr) {
242 reconstruction[ridx] = rec_addr;
243 } else if ((ridx + 1) < reconstructionEntries &&
244 reconstruction[ridx + 1] == MaxAddr) {
245 reconstruction[ridx + 1] = rec_addr;
246 } else if ((ridx + 2) < reconstructionEntries &&
247 reconstruction[ridx + 2] == MaxAddr) {
248 reconstruction[ridx + 2] = rec_addr;
249 } else if ((ridx > 0) &&
250 ((ridx - 1) < reconstructionEntries) &&
251 reconstruction[ridx - 1] == MaxAddr) {
252 reconstruction[ridx - 1] = rec_addr;
253 } else if ((ridx > 1) &&
254 ((ridx - 2) < reconstructionEntries) &&
255 reconstruction[ridx - 2] == MaxAddr) {
256 reconstruction[ridx - 2] = rec_addr;
257 }
258 }
259 }
260 }
261 idx += (it+1)->delta + 1;
262 }
263
264 for (Addr pf_addr : reconstruction) {
265 if (pf_addr != MaxAddr) {
266 addresses.push_back(AddrPriority(pf_addr, 0));
267 }
268 }
269}
270
271} // namespace prefetch
272} // 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
Addr getPC() const
Returns the program counter that generated this request.
Definition base.hh:156
bool isSecure() const
Returns true if the address targets the secure memory space.
Definition base.hh:147
Addr getPaddr() const
Gets the physical address of the request.
Definition base.hh:203
bool isCacheMiss() const
Check if this event comes from a cache miss.
Definition base.hh:212
Addr getAddr() const
Obtains the address value of this Prefetcher address.
Definition base.hh:138
bool hasPC() const
Returns true if the associated program counter is valid.
Definition base.hh:166
unsigned blkSize
The block size of the parent cache.
Definition base.hh:286
std::pair< Addr, int32_t > AddrPriority
Definition queued.hh:192
unsigned int lastTriggerCounter
Counter to keep the count of accesses between trigger accesses.
void calculatePrefetch(const PrefetchInfo &pfi, std::vector< AddrPriority > &addresses, const CacheAccessor &cache) override
void addToRMOB(Addr sr_addr, Addr pst_addr, unsigned int delta)
Adds an entry to the RMOB.
AssociativeCache< ActiveGenerationTableEntry > patternSequenceTable
Pattern Sequence Table (PST)
void checkForActiveGenerationsEnd(const CacheAccessor &cache)
Checks if the active generations have ended.
CircularQueue< RegionMissOrderBufferEntry > rmob
Region Miss Order Buffer (RMOB)
bool addDuplicateEntriesToRMOB
Add duplicate entries to RMOB
const size_t spatialRegionSizeBits
log_2 of the spatial region size
STeMS(const STeMSPrefetcherParams &p)
const unsigned int reconstructionEntries
Number of reconstruction entries.
void reconstructSequence(CircularQueue< RegionMissOrderBufferEntry >::iterator rmob_it, std::vector< AddrPriority > &addresses)
Reconstructs a sequence of accesses and generates the prefetch addresses, adding them to the addresse...
AssociativeCache< ActiveGenerationTableEntry > activeGenerationTable
Active Generation Table (AGT)
const size_t spatialRegionSize
Size of each spatial region.
STL vector class.
Definition stl.hh:37
static constexpr std::enable_if_t< std::is_integral_v< T >, int > floorLog2(T x)
Definition intmath.hh:59
static constexpr bool isPowerOf2(const T &n)
Definition intmath.hh:98
#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
Bitfield< 4 > pc
Bitfield< 0 > p
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.
virtual bool inCache(Addr addr, bool is_secure) const =0
Determine if address is in cache.
virtual bool inMissQueue(Addr addr, bool is_secure) const =0
Determine if address is in cache miss queue.
Iterator to the circular queue.
Entry data type for the Active Generation Table (AGT) and the Pattern Sequence Table (PST)
void addOffset(unsigned int offset)
Add a new access to the sequence.
Data type of the Region Miss Order Buffer entry.
Addr pstAddress
Address used to index the PST table, generated using the PC and the offset within the spatial region.
unsigned int delta
Delta within the global miss order sequence.
const std::string & name()
Definition trace.cc:48

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