gem5  v22.0.0.2
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
gem5::prefetch::Base::PrefetchInfo::getAddr
Addr getAddr() const
Obtains the address value of this Prefetcher address.
Definition: base.hh:125
associative_set_impl.hh
gem5::prefetch::STeMS::checkForActiveGenerationsEnd
void checkForActiveGenerationsEnd()
Checks if the active generations have ended.
Definition: spatio_temporal_memory_streaming.cc:67
gem5::prefetch::STeMS::ActiveGenerationTableEntry
Entry data type for the Active Generation Table (AGT) and the Pattern Sequence Table (PST)
Definition: spatio_temporal_memory_streaming.hh:73
gem5::prefetch::Queued::AddrPriority
std::pair< Addr, int32_t > AddrPriority
Definition: queued.hh:191
gem5::prefetch::Base::PrefetchInfo::isSecure
bool isSecure() const
Returns true if the address targets the secure memory space.
Definition: base.hh:134
gem5::prefetch::STeMS::spatialRegionSize
const size_t spatialRegionSize
Size of each spatial region.
Definition: spatio_temporal_memory_streaming.hh:63
gem5::prefetch::STeMS::calculatePrefetch
void calculatePrefetch(const PrefetchInfo &pfi, std::vector< AddrPriority > &addresses) override
Definition: spatio_temporal_memory_streaming.cc:138
gem5::prefetch::STeMS::reconstructSequence
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...
Definition: spatio_temporal_memory_streaming.cc:206
gem5::prefetch::STeMS::RegionMissOrderBufferEntry::srAddress
Addr srAddress
Address of the spatial region.
Definition: spatio_temporal_memory_streaming.hh:165
gem5::prefetch::STeMS::ActiveGenerationTableEntry::paddress
Addr paddress
Physical address of the spatial region.
Definition: spatio_temporal_memory_streaming.hh:76
gem5::prefetch::STeMS::RegionMissOrderBufferEntry::delta
unsigned int delta
Delta within the global miss order sequence.
Definition: spatio_temporal_memory_streaming.hh:172
gem5::floorLog2
static constexpr std::enable_if_t< std::is_integral_v< T >, int > floorLog2(T x)
Definition: intmath.hh:59
gem5::prefetch::Base::inMissQueue
bool inMissQueue(Addr addr, bool is_secure) const
Determine if address is in cache miss queue.
Definition: base.cc:195
gem5::prefetch::Base::PrefetchInfo::isCacheMiss
bool isCacheMiss() const
Check if this event comes from a cache miss.
Definition: base.hh:199
std::vector
STL vector class.
Definition: stl.hh:37
gem5::prefetch::Base::PrefetchInfo::getPaddr
Addr getPaddr() const
Gets the physical address of the request.
Definition: base.hh:190
gem5::isPowerOf2
static constexpr bool isPowerOf2(const T &n)
Definition: intmath.hh:98
gem5::prefetch::STeMS::addToRMOB
void addToRMOB(Addr sr_addr, Addr pst_addr, unsigned int delta)
Adds an entry to the RMOB.
Definition: spatio_temporal_memory_streaming.cc:117
gem5::prefetch::STeMS::ActiveGenerationTableEntry::pc
Addr pc
PC that started this generation.
Definition: spatio_temporal_memory_streaming.hh:78
gem5::prefetch::Base::PrefetchInfo::getPC
Addr getPC() const
Returns the program counter that generated this request.
Definition: base.hh:143
gem5::VegaISA::p
Bitfield< 54 > p
Definition: pagetable.hh:70
gem5::prefetch::STeMS::addDuplicateEntriesToRMOB
bool addDuplicateEntriesToRMOB
Add duplicate entries to RMOB
Definition: spatio_temporal_memory_streaming.hh:179
gem5::CircularQueue::iterator
Iterator to the circular queue.
Definition: circular_queue.hh:85
gem5::prefetch::STeMS::RegionMissOrderBufferEntry::pstAddress
Addr pstAddress
Address used to index the PST table, generated using the PC and the offset within the spatial region.
Definition: spatio_temporal_memory_streaming.hh:170
gem5::prefetch::STeMS::spatialRegionSizeBits
const size_t spatialRegionSizeBits
log_2 of the spatial region size
Definition: spatio_temporal_memory_streaming.hh:65
gem5::MaxAddr
const Addr MaxAddr
Definition: types.hh:171
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:186
gem5::prefetch::STeMS::ActiveGenerationTableEntry::addOffset
void addOffset(unsigned int offset)
Add a new access to the sequence.
Definition: spatio_temporal_memory_streaming.hh:135
gem5::Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
gem5::prefetch::STeMS::ActiveGenerationTableEntry::update
void update(ActiveGenerationTableEntry const &e)
Update the entry data with an entry from a generation that just ended.
Definition: spatio_temporal_memory_streaming.hh:123
gem5::GEM5_DEPRECATED_NAMESPACE
GEM5_DEPRECATED_NAMESPACE(GuestABI, guest_abi)
gem5::prefetch::Queued
Definition: queued.hh:60
gem5::prefetch::STeMS::STeMS
STeMS(const STeMSPrefetcherParams &p)
Definition: spatio_temporal_memory_streaming.cc:42
gem5::prefetch::STeMS::rmob
CircularQueue< RegionMissOrderBufferEntry > rmob
Region Miss Order Buffer (RMOB)
Definition: spatio_temporal_memory_streaming.hh:176
gem5::MipsISA::pc
Bitfield< 4 > pc
Definition: pra_constants.hh:243
gem5::prefetch::STeMS::activeGenerationTable
AssociativeSet< ActiveGenerationTableEntry > activeGenerationTable
Active Generation Table (AGT)
Definition: spatio_temporal_memory_streaming.hh:157
gem5::prefetch::STeMS::reconstructionEntries
const unsigned int reconstructionEntries
Number of reconstruction entries.
Definition: spatio_temporal_memory_streaming.hh:67
gem5::prefetch::STeMS::patternSequenceTable
AssociativeSet< ActiveGenerationTableEntry > patternSequenceTable
Pattern Sequence Table (PST)
Definition: spatio_temporal_memory_streaming.hh:159
gem5::prefetch::Base::blkSize
unsigned blkSize
The block size of the parent cache.
Definition: base.hh:270
gem5::prefetch::STeMS::lastTriggerCounter
unsigned int lastTriggerCounter
Counter to keep the count of accesses between trigger accesses.
Definition: spatio_temporal_memory_streaming.hh:182
gem5::context_switch_task_id::Prefetcher
@ Prefetcher
Definition: request.hh:83
gem5::prefetch::Base::inCache
bool inCache(Addr addr, bool is_secure) const
Determine if address is in cache.
Definition: base.cc:189
fatal_if
#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
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: gpu_translation_state.hh:37
gem5::prefetch::STeMS::ActiveGenerationTableEntry::sequence
std::vector< SequenceEntry > sequence
Sequence of accesses.
Definition: spatio_temporal_memory_streaming.hh:95
spatio_temporal_memory_streaming.hh
gem5::prefetch::STeMS::RegionMissOrderBufferEntry
Data type of the Region Miss Order Buffer entry.
Definition: spatio_temporal_memory_streaming.hh:162
gem5::prefetch::Base::PrefetchInfo
Class containing the information needed by the prefetch to train and generate new prefetch requests.
Definition: base.hh:97
gem5::prefetch::Base::PrefetchInfo::hasPC
bool hasPC() const
Returns true if the associated program counter is valid.
Definition: base.hh:153

Generated on Thu Jul 28 2022 13:32:34 for gem5 by doxygen 1.8.17