gem5 v24.0.0.0
Loading...
Searching...
No Matches
spatio_temporal_memory_streaming.cc
Go to the documentation of this file.
1
30
31#include "debug/HWPrefetch.hh"
33#include "params/STeMSPrefetcher.hh"
34
35namespace gem5
36{
37
38namespace prefetch
39{
40
41STeMS::STeMS(const STeMSPrefetcherParams &p)
42 : Queued(p), spatialRegionSize(p.spatial_region_size),
43 spatialRegionSizeBits(floorLog2(p.spatial_region_size)),
44 reconstructionEntries(p.reconstruction_entries),
45 activeGenerationTable((name() + ".ActiveGenerationTable").c_str(),
46 p.active_generation_table_entries,
47 p.active_generation_table_assoc,
48 p.active_generation_table_replacement_policy,
49 p.active_generation_table_indexing_policy,
51 spatialRegionSize / blkSize)),
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 rmob(p.region_miss_order_buffer_entries),
60 addDuplicateEntriesToRMOB(p.add_duplicate_entries_to_rmob),
61 lastTriggerCounter(0)
62{
64 "The spatial region size must be a power of 2.");
65}
66
67void
69{
70 // This prefetcher operates attached to the L1 and it observes all
71 // accesses, this guarantees that no evictions are missed
72
73 // Iterate over all entries, if any recorded cacheline has been evicted,
74 // the generation finishes, move the entry to the PST
75 for (auto &agt_entry : activeGenerationTable) {
76 if (agt_entry.isValid()) {
77 bool generation_ended = false;
78 bool sr_is_secure = agt_entry.isSecure();
79 Addr pst_addr = 0;
80 for (auto &seq_entry : agt_entry.sequence) {
81 if (seq_entry.counter > 0) {
82 Addr cache_addr =
83 agt_entry.paddress + seq_entry.offset * blkSize;
84 if (!cache.inCache(cache_addr, sr_is_secure) &&
85 !cache.inMissQueue(cache_addr, sr_is_secure)) {
86 generation_ended = true;
87 pst_addr = (agt_entry.pc << spatialRegionSizeBits)
88 + seq_entry.offset;
89 break;
90 }
91 }
92 }
93 if (generation_ended) {
94 // PST is indexed using the PC (secure bit is unused)
95 auto pst_entry = patternSequenceTable.findEntry(pst_addr);
96 if (pst_entry == nullptr) {
97 // Tipically an entry will not exist
98 pst_entry = patternSequenceTable.findVictim(pst_addr);
99 assert(pst_entry != nullptr);
100 patternSequenceTable.insertEntry(pst_addr, pst_entry);
101 } else {
102 patternSequenceTable.accessEntry(pst_entry);
103 }
104 // If the entry existed, this will update the values, if not,
105 // this also sets the values of the entry
106 pst_entry->update(agt_entry);
107 // Free the AGT entry
108 activeGenerationTable.invalidate(&agt_entry);
109 }
110 }
111 }
112}
113
114void
115STeMS::addToRMOB(Addr sr_addr, Addr pst_addr, unsigned int delta)
116{
118 rmob_entry.srAddress = sr_addr;
119 rmob_entry.pstAddress = pst_addr;
120 rmob_entry.delta = delta;
121
123 for (const auto& entry : rmob) {
124 if (entry.srAddress == sr_addr &&
125 entry.pstAddress == pst_addr &&
126 entry.delta == delta) {
127 return;
128 }
129 }
130 }
131
132 rmob.push_back(rmob_entry);
133}
134
135void
137 std::vector<AddrPriority> &addresses,
138 const CacheAccessor &cache)
139{
140 if (!pfi.hasPC()) {
141 DPRINTF(HWPrefetch, "Ignoring request with no PC.\n");
142 return;
143 }
144
145 Addr pc = pfi.getPC();
146 bool is_secure = pfi.isSecure();
147 // Spatial region address
148 Addr sr_addr = pfi.getAddr() / spatialRegionSize;
149 Addr paddr = pfi.getPaddr();
150
151 // Offset in cachelines within the spatial region
152 Addr sr_offset = (pfi.getAddr() % spatialRegionSize) / blkSize;
153
154 // Check if any active generation has ended
156
157 ActiveGenerationTableEntry *agt_entry =
158 activeGenerationTable.findEntry(sr_addr, is_secure);
159 if (agt_entry != nullptr) {
160 // found an entry in the AGT, entry is currently being recorded,
161 // add the offset
162 activeGenerationTable.accessEntry(agt_entry);
163 agt_entry->addOffset(sr_offset);
165 } else {
166 // Not found, this is the first access (Trigger access)
167
168 // Add entry to RMOB
169 Addr pst_addr = (pc << spatialRegionSizeBits) + sr_offset;
170 addToRMOB(sr_addr, pst_addr, lastTriggerCounter);
171 // Reset last trigger counter
173
174 // allocate a new AGT entry
175 agt_entry = activeGenerationTable.findVictim(sr_addr);
176 assert(agt_entry != nullptr);
177 activeGenerationTable.insertEntry(sr_addr, is_secure, agt_entry);
178 agt_entry->pc = pc;
179 agt_entry->paddress = paddr;
180 agt_entry->addOffset(sr_offset);
181 }
182 // increase the seq Counter for other entries
183 for (auto &agt_e : activeGenerationTable) {
184 if (agt_e.isValid() && agt_entry != &agt_e) {
185 agt_e.seqCounter += 1;
186 }
187 }
188
189 // Prefetch generation: if this is a miss, search for the most recent
190 // entry in the RMOB, and reconstruct the registered access sequence
191 if (pfi.isCacheMiss()) {
192 auto it = rmob.end();
193 while (it != rmob.begin()) {
194 --it;
195 if (it->srAddress == sr_addr) {
196 // reconstruct the access sequence
197 reconstructSequence(it, addresses);
198 break;
199 }
200 }
201 }
202}
203
204void
207 std::vector<AddrPriority> &addresses)
208{
210 unsigned int idx = 0;
211
212 // Process rmob entries from rmob_it (most recent with address = sr_addr)
213 // to the latest one
214 for (auto it = rmob_it; it != rmob.end() && (idx < reconstructionEntries);
215 it++) {
216 reconstruction[idx] = it->srAddress * spatialRegionSize;
217 idx += (it+1)->delta + 1;
218 }
219
220 // Now query the PST with the PC of each RMOB entry
221 idx = 0;
222 for (auto it = rmob_it; it != rmob.end() && (idx < reconstructionEntries);
223 it++) {
224 auto pst_entry = patternSequenceTable.findEntry(it->pstAddress);
225 if (pst_entry != nullptr) {
226 patternSequenceTable.accessEntry(pst_entry);
227 for (auto &seq_entry : pst_entry->sequence) {
228 if (seq_entry.counter > 1) {
229 // 2-bit counter: high enough confidence with a
230 // value greater than 1
231 Addr rec_addr = it->srAddress * spatialRegionSize +
232 seq_entry.offset;
233 unsigned ridx = idx + seq_entry.delta;
234 // Try to use the corresponding position, if it has been
235 // already used, look the surrounding positions
236 if (ridx < reconstructionEntries &&
237 reconstruction[ridx] == MaxAddr) {
238 reconstruction[ridx] = rec_addr;
239 } else if ((ridx + 1) < reconstructionEntries &&
240 reconstruction[ridx + 1] == MaxAddr) {
241 reconstruction[ridx + 1] = rec_addr;
242 } else if ((ridx + 2) < reconstructionEntries &&
243 reconstruction[ridx + 2] == MaxAddr) {
244 reconstruction[ridx + 2] = rec_addr;
245 } else if ((ridx > 0) &&
246 ((ridx - 1) < reconstructionEntries) &&
247 reconstruction[ridx - 1] == MaxAddr) {
248 reconstruction[ridx - 1] = rec_addr;
249 } else if ((ridx > 1) &&
250 ((ridx - 2) < reconstructionEntries) &&
251 reconstruction[ridx - 2] == MaxAddr) {
252 reconstruction[ridx - 2] = rec_addr;
253 }
254 }
255 }
256 }
257 idx += (it+1)->delta + 1;
258 }
259
260 for (Addr pf_addr : reconstruction) {
261 if (pf_addr != MaxAddr) {
262 addresses.push_back(AddrPriority(pf_addr, 0));
263 }
264 }
265}
266
267} // namespace prefetch
268} // 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
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.
AssociativeSet< ActiveGenerationTableEntry > activeGenerationTable
Active Generation Table (AGT)
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...
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 - 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.
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 Tue Jun 18 2024 16:24:05 for gem5 by doxygen 1.11.0