gem5  v22.1.0.0
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 
35 namespace gem5
36 {
37 
39 namespace prefetch
40 {
41 
42 STeMS::STeMS(const STeMSPrefetcherParams &p)
43  : Queued(p), spatialRegionSize(p.spatial_region_size),
44  spatialRegionSizeBits(floorLog2(p.spatial_region_size)),
45  reconstructionEntries(p.reconstruction_entries),
46  activeGenerationTable(p.active_generation_table_assoc,
47  p.active_generation_table_entries,
48  p.active_generation_table_indexing_policy,
49  p.active_generation_table_replacement_policy,
51  spatialRegionSize / blkSize)),
52  patternSequenceTable(p.pattern_sequence_table_assoc,
53  p.pattern_sequence_table_entries,
54  p.pattern_sequence_table_indexing_policy,
55  p.pattern_sequence_table_replacement_policy,
57  spatialRegionSize / blkSize)),
58  rmob(p.region_miss_order_buffer_entries),
59  addDuplicateEntriesToRMOB(p.add_duplicate_entries_to_rmob),
60  lastTriggerCounter(0)
61 {
63  "The spatial region size must be a power of 2.");
64 }
65 
66 void
68 {
69  // This prefetcher operates attached to the L1 and it observes all
70  // accesses, this guarantees that no evictions are missed
71 
72  // Iterate over all entries, if any recorded cacheline has been evicted,
73  // the generation finishes, move the entry to the PST
74  for (auto &agt_entry : activeGenerationTable) {
75  if (agt_entry.isValid()) {
76  bool generation_ended = false;
77  bool sr_is_secure = agt_entry.isSecure();
78  Addr pst_addr = 0;
79  for (auto &seq_entry : agt_entry.sequence) {
80  if (seq_entry.counter > 0) {
81  Addr cache_addr =
82  agt_entry.paddress + seq_entry.offset * blkSize;
83  if (!inCache(cache_addr, sr_is_secure) &&
84  !inMissQueue(cache_addr, sr_is_secure)) {
85  generation_ended = true;
86  pst_addr = (agt_entry.pc << spatialRegionSizeBits)
87  + seq_entry.offset;
88  break;
89  }
90  }
91  }
92  if (generation_ended) {
93  // PST is indexed using the PC (secure bit is unused)
94  ActiveGenerationTableEntry *pst_entry =
95  patternSequenceTable.findEntry(pst_addr,
96  false /*unused*/);
97  if (pst_entry == nullptr) {
98  // Tipically an entry will not exist
99  pst_entry = patternSequenceTable.findVictim(pst_addr);
100  assert(pst_entry != nullptr);
101  patternSequenceTable.insertEntry(pst_addr,
102  false /*unused*/, 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 
116 void
117 STeMS::addToRMOB(Addr sr_addr, Addr pst_addr, unsigned int delta)
118 {
119  RegionMissOrderBufferEntry rmob_entry;
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 
137 void
139  std::vector<AddrPriority> &addresses)
140 {
141  if (!pfi.hasPC()) {
142  DPRINTF(HWPrefetch, "Ignoring request with no PC.\n");
143  return;
144  }
145 
146  Addr pc = pfi.getPC();
147  bool is_secure = pfi.isSecure();
148  // Spatial region address
149  Addr sr_addr = pfi.getAddr() / spatialRegionSize;
150  Addr paddr = pfi.getPaddr();
151 
152  // Offset in cachelines within the spatial region
153  Addr sr_offset = (pfi.getAddr() % spatialRegionSize) / blkSize;
154 
155  // Check if any active generation has ended
157 
158  ActiveGenerationTableEntry *agt_entry =
159  activeGenerationTable.findEntry(sr_addr, is_secure);
160  if (agt_entry != nullptr) {
161  // found an entry in the AGT, entry is currently being recorded,
162  // add the offset
163  activeGenerationTable.accessEntry(agt_entry);
164  agt_entry->addOffset(sr_offset);
165  lastTriggerCounter += 1;
166  } else {
167  // Not found, this is the first access (Trigger access)
168 
169  // Add entry to RMOB
170  Addr pst_addr = (pc << spatialRegionSizeBits) + sr_offset;
171  addToRMOB(sr_addr, pst_addr, lastTriggerCounter);
172  // Reset last trigger counter
173  lastTriggerCounter = 0;
174 
175  // allocate a new AGT entry
176  agt_entry = activeGenerationTable.findVictim(sr_addr);
177  assert(agt_entry != nullptr);
178  activeGenerationTable.insertEntry(sr_addr, is_secure, agt_entry);
179  agt_entry->pc = pc;
180  agt_entry->paddress = paddr;
181  agt_entry->addOffset(sr_offset);
182  }
183  // increase the seq Counter for other entries
184  for (auto &agt_e : activeGenerationTable) {
185  if (agt_e.isValid() && agt_entry != &agt_e) {
186  agt_e.seqCounter += 1;
187  }
188  }
189 
190  // Prefetch generation: if this is a miss, search for the most recent
191  // entry in the RMOB, and reconstruct the registered access sequence
192  if (pfi.isCacheMiss()) {
193  auto it = rmob.end();
194  while (it != rmob.begin()) {
195  --it;
196  if (it->srAddress == sr_addr) {
197  // reconstruct the access sequence
198  reconstructSequence(it, addresses);
199  break;
200  }
201  }
202  }
203 }
204 
205 void
208  std::vector<AddrPriority> &addresses)
209 {
211  unsigned int idx = 0;
212 
213  // Process rmob entries from rmob_it (most recent with address = sr_addr)
214  // to the latest one
215  for (auto it = rmob_it; it != rmob.end() && (idx < reconstructionEntries);
216  it++) {
217  reconstruction[idx] = it->srAddress * spatialRegionSize;
218  idx += (it+1)->delta + 1;
219  }
220 
221  // Now query the PST with the PC of each RMOB entry
222  idx = 0;
223  for (auto it = rmob_it; it != rmob.end() && (idx < reconstructionEntries);
224  it++) {
225  ActiveGenerationTableEntry *pst_entry =
226  patternSequenceTable.findEntry(it->pstAddress, false /* unused */);
227  if (pst_entry != nullptr) {
228  patternSequenceTable.accessEntry(pst_entry);
229  for (auto &seq_entry : pst_entry->sequence) {
230  if (seq_entry.counter > 1) {
231  // 2-bit counter: high enough confidence with a
232  // value greater than 1
233  Addr rec_addr = it->srAddress * spatialRegionSize +
234  seq_entry.offset;
235  unsigned ridx = idx + seq_entry.delta;
236  // Try to use the corresponding position, if it has been
237  // already used, look the surrounding positions
238  if (ridx < reconstructionEntries &&
239  reconstruction[ridx] == MaxAddr) {
240  reconstruction[ridx] = rec_addr;
241  } else if ((ridx + 1) < reconstructionEntries &&
242  reconstruction[ridx + 1] == MaxAddr) {
243  reconstruction[ridx + 1] = rec_addr;
244  } else if ((ridx + 2) < reconstructionEntries &&
245  reconstruction[ridx + 2] == MaxAddr) {
246  reconstruction[ridx + 2] = rec_addr;
247  } else if ((ridx > 0) &&
248  ((ridx - 1) < reconstructionEntries) &&
249  reconstruction[ridx - 1] == MaxAddr) {
250  reconstruction[ridx - 1] = rec_addr;
251  } else if ((ridx > 1) &&
252  ((ridx - 2) < reconstructionEntries) &&
253  reconstruction[ridx - 2] == MaxAddr) {
254  reconstruction[ridx - 2] = rec_addr;
255  }
256  }
257  }
258  }
259  idx += (it+1)->delta + 1;
260  }
261 
262  for (Addr pf_addr : reconstruction) {
263  if (pf_addr != MaxAddr) {
264  addresses.push_back(AddrPriority(pf_addr, 0));
265  }
266  }
267 }
268 
269 } // namespace prefetch
270 } // namespace gem5
#define DPRINTF(x,...)
Definition: trace.hh:186
Class containing the information needed by the prefetch to train and generate new prefetch requests.
Definition: base.hh:98
Addr getPC() const
Returns the program counter that generated this request.
Definition: base.hh:143
bool isSecure() const
Returns true if the address targets the secure memory space.
Definition: base.hh:134
Addr getPaddr() const
Gets the physical address of the request.
Definition: base.hh:190
bool isCacheMiss() const
Check if this event comes from a cache miss.
Definition: base.hh:199
Addr getAddr() const
Obtains the address value of this Prefetcher address.
Definition: base.hh:125
bool hasPC() const
Returns true if the associated program counter is valid.
Definition: base.hh:153
unsigned blkSize
The block size of the parent cache.
Definition: base.hh:270
bool inCache(Addr addr, bool is_secure) const
Determine if address is in cache.
Definition: base.cc:189
bool inMissQueue(Addr addr, bool is_secure) const
Determine if address is in cache miss queue.
Definition: base.cc:195
std::pair< Addr, int32_t > AddrPriority
Definition: queued.hh:191
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:226
Bitfield< 4 > pc
Bitfield< 54 > p
Definition: pagetable.hh:70
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
GEM5_DEPRECATED_NAMESPACE(GuestABI, guest_abi)
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 Wed Dec 21 2022 10:22:36 for gem5 by doxygen 1.9.1