gem5  v21.1.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 {
61  "The spatial region size must be a power of 2.");
62 }
63 
64 void
66 {
67  // This prefetcher operates attached to the L1 and it observes all
68  // accesses, this guarantees that no evictions are missed
69 
70  // Iterate over all entries, if any recorded cacheline has been evicted,
71  // the generation finishes, move the entry to the PST
72  for (auto &agt_entry : activeGenerationTable) {
73  if (agt_entry.isValid()) {
74  bool generation_ended = false;
75  bool sr_is_secure = agt_entry.isSecure();
76  for (auto &seq_entry : agt_entry.sequence) {
77  if (seq_entry.counter > 0) {
78  Addr cache_addr =
79  agt_entry.paddress + seq_entry.offset * blkSize;
80  if (!inCache(cache_addr, sr_is_secure) &&
81  !inMissQueue(cache_addr, sr_is_secure)) {
82  generation_ended = true;
83  break;
84  }
85  }
86  }
87  if (generation_ended) {
88  // PST is indexed using the PC (secure bit is unused)
89  ActiveGenerationTableEntry *pst_entry =
90  patternSequenceTable.findEntry(agt_entry.pc,
91  false /*unused*/);
92  if (pst_entry == nullptr) {
93  // Tipically an entry will not exist
94  pst_entry = patternSequenceTable.findVictim(agt_entry.pc);
95  assert(pst_entry != nullptr);
96  patternSequenceTable.insertEntry(agt_entry.pc,
97  false /*unused*/, pst_entry);
98  } else {
99  patternSequenceTable.accessEntry(pst_entry);
100  }
101  // If the entry existed, this will update the values, if not,
102  // this also sets the values of the entry
103  pst_entry->update(agt_entry);
104  // Free the AGT entry
105  activeGenerationTable.invalidate(&agt_entry);
106  }
107  }
108  }
109 }
110 
111 void
112 STeMS::addToRMOB(Addr sr_addr, Addr pst_addr, unsigned int delta)
113 {
114  RegionMissOrderBufferEntry rmob_entry;
115  rmob_entry.srAddress = sr_addr;
116  rmob_entry.pstAddress = pst_addr;
117  rmob_entry.delta = delta;
118 
119  rmob.push_back(rmob_entry);
120 }
121 
122 void
124  std::vector<AddrPriority> &addresses)
125 {
126  if (!pfi.hasPC()) {
127  DPRINTF(HWPrefetch, "Ignoring request with no PC.\n");
128  return;
129  }
130 
131  Addr pc = pfi.getPC();
132  bool is_secure = pfi.isSecure();
133  // Spatial region address
134  Addr sr_addr = pfi.getAddr() / spatialRegionSize;
135  Addr paddr = pfi.getPaddr();
136 
137  // Offset in cachelines within the spatial region
138  Addr sr_offset = (pfi.getAddr() % spatialRegionSize) / blkSize;
139 
140  // Check if any active generation has ended
142 
143  ActiveGenerationTableEntry *agt_entry =
144  activeGenerationTable.findEntry(sr_addr, is_secure);
145  if (agt_entry != nullptr) {
146  // found an entry in the AGT, entry is currently being recorded,
147  // add the offset
148  activeGenerationTable.accessEntry(agt_entry);
149  agt_entry->addOffset(sr_offset);
150  lastTriggerCounter += 1;
151  } else {
152  // Not found, this is the first access (Trigger access)
153 
154  // Add entry to RMOB
155  Addr pst_addr = (pc << spatialRegionSizeBits) + sr_offset;
156  addToRMOB(sr_addr, pst_addr, lastTriggerCounter);
157  // Reset last trigger counter
158  lastTriggerCounter = 0;
159 
160  // allocate a new AGT entry
161  agt_entry = activeGenerationTable.findVictim(sr_addr);
162  assert(agt_entry != nullptr);
163  activeGenerationTable.insertEntry(sr_addr, is_secure, agt_entry);
164  agt_entry->pc = pc;
165  agt_entry->paddress = paddr;
166  agt_entry->addOffset(sr_offset);
167  }
168  // increase the seq Counter for other entries
169  for (auto &agt_e : activeGenerationTable) {
170  if (agt_e.isValid() && agt_entry != &agt_e) {
171  agt_e.seqCounter += 1;
172  }
173  }
174 
175  // Prefetch generation: if this is a miss, search for the most recent
176  // entry in the RMOB, and reconstruct the registered access sequence
177  if (pfi.isCacheMiss()) {
178  auto it = rmob.end();
179  while (it != rmob.begin()) {
180  --it;
181  if (it->srAddress == sr_addr) {
182  // reconstruct the access sequence
183  reconstructSequence(it, addresses);
184  break;
185  }
186  }
187  }
188 }
189 
190 void
193  std::vector<AddrPriority> &addresses)
194 {
196  unsigned int idx = 0;
197 
198  // Process rmob entries from rmob_it (most recent with address = sr_addr)
199  // to the latest one
200  for (auto it = rmob_it; it != rmob.end() && (idx < reconstructionEntries);
201  it++) {
202  reconstruction[idx] = it->srAddress * spatialRegionSize;
203  idx += (it+1)->delta + 1;
204  }
205 
206  // Now query the PST with the PC of each RMOB entry
207  idx = 0;
208  for (auto it = rmob_it; it != rmob.end() && (idx < reconstructionEntries);
209  it++) {
210  ActiveGenerationTableEntry *pst_entry =
211  patternSequenceTable.findEntry(it->pstAddress, false /* unused */);
212  if (pst_entry != nullptr) {
213  patternSequenceTable.accessEntry(pst_entry);
214  for (auto &seq_entry : pst_entry->sequence) {
215  if (seq_entry.counter > 1) {
216  // 2-bit counter: high enough confidence with a
217  // value greater than 1
218  Addr rec_addr = it->srAddress * spatialRegionSize +
219  seq_entry.offset;
220  unsigned ridx = idx + seq_entry.delta;
221  // Try to use the corresponding position, if it has been
222  // already used, look the surrounding positions
223  if (ridx < reconstructionEntries &&
224  reconstruction[ridx] == MaxAddr) {
225  reconstruction[ridx] = rec_addr;
226  } else if ((ridx + 1) < reconstructionEntries &&
227  reconstruction[ridx + 1] == MaxAddr) {
228  reconstruction[ridx + 1] = rec_addr;
229  } else if ((ridx + 2) < reconstructionEntries &&
230  reconstruction[ridx + 2] == MaxAddr) {
231  reconstruction[ridx + 2] = rec_addr;
232  } else if ((ridx > 0) &&
233  ((ridx - 1) < reconstructionEntries) &&
234  reconstruction[ridx - 1] == MaxAddr) {
235  reconstruction[ridx - 1] = rec_addr;
236  } else if ((ridx > 1) &&
237  ((ridx - 2) < reconstructionEntries) &&
238  reconstruction[ridx - 2] == MaxAddr) {
239  reconstruction[ridx - 2] = rec_addr;
240  }
241  }
242  }
243  }
244  idx += (it+1)->delta + 1;
245  }
246 
247  for (Addr pf_addr : reconstruction) {
248  if (pf_addr != MaxAddr) {
249  addresses.push_back(AddrPriority(pf_addr, 0));
250  }
251  }
252 }
253 
254 } // namespace prefetch
255 } // 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:65
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:190
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:123
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:191
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::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:112
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::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::MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:326
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::floorLog2
static constexpr std::enable_if_t< std::is_integral< T >::value, int > floorLog2(T x)
Definition: intmath.hh:59
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:179
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:225
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: decoder.cc:40
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 Tue Sep 21 2021 12:25:29 for gem5 by doxygen 1.8.17