gem5 v23.0.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"
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(p.active_generation_table_assoc,
46 p.active_generation_table_entries,
47 p.active_generation_table_indexing_policy,
48 p.active_generation_table_replacement_policy,
50 spatialRegionSize / blkSize)),
51 patternSequenceTable(p.pattern_sequence_table_assoc,
52 p.pattern_sequence_table_entries,
53 p.pattern_sequence_table_indexing_policy,
54 p.pattern_sequence_table_replacement_policy,
56 spatialRegionSize / blkSize)),
57 rmob(p.region_miss_order_buffer_entries),
58 addDuplicateEntriesToRMOB(p.add_duplicate_entries_to_rmob),
59 lastTriggerCounter(0)
60{
62 "The spatial region size must be a power of 2.");
63}
64
65void
67{
68 // This prefetcher operates attached to the L1 and it observes all
69 // accesses, this guarantees that no evictions are missed
70
71 // Iterate over all entries, if any recorded cacheline has been evicted,
72 // the generation finishes, move the entry to the PST
73 for (auto &agt_entry : activeGenerationTable) {
74 if (agt_entry.isValid()) {
75 bool generation_ended = false;
76 bool sr_is_secure = agt_entry.isSecure();
77 Addr pst_addr = 0;
78 for (auto &seq_entry : agt_entry.sequence) {
79 if (seq_entry.counter > 0) {
80 Addr cache_addr =
81 agt_entry.paddress + seq_entry.offset * blkSize;
82 if (!inCache(cache_addr, sr_is_secure) &&
83 !inMissQueue(cache_addr, sr_is_secure)) {
84 generation_ended = true;
85 pst_addr = (agt_entry.pc << spatialRegionSizeBits)
86 + seq_entry.offset;
87 break;
88 }
89 }
90 }
91 if (generation_ended) {
92 // PST is indexed using the PC (secure bit is unused)
94 patternSequenceTable.findEntry(pst_addr,
95 false /*unused*/);
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,
101 false /*unused*/, pst_entry);
102 } else {
103 patternSequenceTable.accessEntry(pst_entry);
104 }
105 // If the entry existed, this will update the values, if not,
106 // this also sets the values of the entry
107 pst_entry->update(agt_entry);
108 // Free the AGT entry
109 activeGenerationTable.invalidate(&agt_entry);
110 }
111 }
112 }
113}
114
115void
116STeMS::addToRMOB(Addr sr_addr, Addr pst_addr, unsigned int delta)
117{
119 rmob_entry.srAddress = sr_addr;
120 rmob_entry.pstAddress = pst_addr;
121 rmob_entry.delta = delta;
122
124 for (const auto& entry : rmob) {
125 if (entry.srAddress == sr_addr &&
126 entry.pstAddress == pst_addr &&
127 entry.delta == delta) {
128 return;
129 }
130 }
131 }
132
133 rmob.push_back(rmob_entry);
134}
135
136void
138 std::vector<AddrPriority> &addresses)
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 ActiveGenerationTableEntry *pst_entry =
225 patternSequenceTable.findEntry(it->pstAddress, false /* unused */);
226 if (pst_entry != nullptr) {
227 patternSequenceTable.accessEntry(pst_entry);
228 for (auto &seq_entry : pst_entry->sequence) {
229 if (seq_entry.counter > 1) {
230 // 2-bit counter: high enough confidence with a
231 // value greater than 1
232 Addr rec_addr = it->srAddress * spatialRegionSize +
233 seq_entry.offset;
234 unsigned ridx = idx + seq_entry.delta;
235 // Try to use the corresponding position, if it has been
236 // already used, look the surrounding positions
237 if (ridx < reconstructionEntries &&
238 reconstruction[ridx] == MaxAddr) {
239 reconstruction[ridx] = rec_addr;
240 } else if ((ridx + 1) < reconstructionEntries &&
241 reconstruction[ridx + 1] == MaxAddr) {
242 reconstruction[ridx + 1] = rec_addr;
243 } else if ((ridx + 2) < reconstructionEntries &&
244 reconstruction[ridx + 2] == MaxAddr) {
245 reconstruction[ridx + 2] = rec_addr;
246 } else if ((ridx > 0) &&
247 ((ridx - 1) < reconstructionEntries) &&
248 reconstruction[ridx - 1] == MaxAddr) {
249 reconstruction[ridx - 1] = rec_addr;
250 } else if ((ridx > 1) &&
251 ((ridx - 2) < reconstructionEntries) &&
252 reconstruction[ridx - 2] == MaxAddr) {
253 reconstruction[ridx - 2] = rec_addr;
254 }
255 }
256 }
257 }
258 idx += (it+1)->delta + 1;
259 }
260
261 for (Addr pf_addr : reconstruction) {
262 if (pf_addr != MaxAddr) {
263 addresses.push_back(AddrPriority(pf_addr, 0));
264 }
265 }
266}
267
268} // namespace prefetch
269} // 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
Addr getPC() const
Returns the program counter that generated this request.
Definition base.hh:142
bool isSecure() const
Returns true if the address targets the secure memory space.
Definition base.hh:133
Addr getPaddr() const
Gets the physical address of the request.
Definition base.hh:189
bool isCacheMiss() const
Check if this event comes from a cache miss.
Definition base.hh:198
Addr getAddr() const
Obtains the address value of this Prefetcher address.
Definition base.hh:124
bool hasPC() const
Returns true if the associated program counter is valid.
Definition base.hh:152
unsigned blkSize
The block size of the parent cache.
Definition base.hh:269
bool inCache(Addr addr, bool is_secure) const
Determine if address is in cache.
Definition base.cc:188
bool inMissQueue(Addr addr, bool is_secure) const
Determine if address is in cache miss queue.
Definition base.cc:194
std::pair< Addr, int32_t > AddrPriority
Definition queued.hh:190
unsigned int lastTriggerCounter
Counter to keep the count of accesses between trigger accesses.
void addToRMOB(Addr sr_addr, Addr pst_addr, unsigned int delta)
Adds an entry to the RMOB.
AssociativeSet< ActiveGenerationTableEntry > activeGenerationTable
Active Generation Table (AGT)
void checkForActiveGenerationsEnd()
Checks if the active generations have ended.
void calculatePrefetch(const PrefetchInfo &pfi, std::vector< AddrPriority > &addresses) override
AssociativeSet< ActiveGenerationTableEntry > patternSequenceTable
Pattern Sequence Table (PST)
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
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
Iterator to the circular queue.
Entry data type for the Active Generation Table (AGT) and the Pattern Sequence Table (PST)
std::vector< SequenceEntry > sequence
Sequence of accesses.
void update(ActiveGenerationTableEntry const &e)
Update the entry data with an entry from a generation that just ended.
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.

Generated on Mon Jul 10 2023 15:32:04 for gem5 by doxygen 1.9.7