gem5  v19.0.0.0
spatio_temporal_memory_streaming.cc
Go to the documentation of this file.
1 
32 
33 #include "debug/HWPrefetch.hh"
35 #include "params/STeMSPrefetcher.hh"
36 
37 STeMSPrefetcher::STeMSPrefetcher(const STeMSPrefetcherParams *p)
38  : QueuedPrefetcher(p), spatialRegionSize(p->spatial_region_size),
39  spatialRegionSizeBits(floorLog2(p->spatial_region_size)),
40  reconstructionEntries(p->reconstruction_entries),
41  activeGenerationTable(p->active_generation_table_assoc,
42  p->active_generation_table_entries,
43  p->active_generation_table_indexing_policy,
44  p->active_generation_table_replacement_policy,
46  spatialRegionSize / blkSize)),
47  patternSequenceTable(p->pattern_sequence_table_assoc,
48  p->pattern_sequence_table_entries,
49  p->pattern_sequence_table_indexing_policy,
50  p->pattern_sequence_table_replacement_policy,
52  spatialRegionSize / blkSize)),
53  rmob(p->region_miss_order_buffer_entries), rmobHead(0)
54 {
56  "The spatial region size must be a power of 2.");
57 }
58 
59 void
61  // This prefetcher operates attached to the L1 and it observes all
62  // accesses, this guarantees that no evictions are missed
63 
64  // Iterate over all entries, if any recorded cacheline has been evicted,
65  // the generation finishes, move the entry to the PST
66  for (auto &agt_entry : activeGenerationTable) {
67  if (agt_entry.isValid()) {
68  bool generation_ended = false;
69  bool sr_is_secure = agt_entry.isSecure();
70  for (auto &seq_entry : agt_entry.sequence) {
71  if (seq_entry.counter > 0) {
72  Addr cache_addr =
73  agt_entry.paddress + seq_entry.offset * blkSize;
74  if (!inCache(cache_addr, sr_is_secure) &&
75  !inMissQueue(cache_addr, sr_is_secure)) {
76  generation_ended = true;
77  break;
78  }
79  }
80  }
81  if (generation_ended) {
82  // PST is indexed using the PC (secure bit is unused)
83  ActiveGenerationTableEntry *pst_entry =
84  patternSequenceTable.findEntry(agt_entry.pc,
85  false /*unused*/);
86  if (pst_entry == nullptr) {
87  // Tipically an entry will not exist
88  pst_entry = patternSequenceTable.findVictim(agt_entry.pc);
89  assert(pst_entry != nullptr);
90  patternSequenceTable.insertEntry(agt_entry.pc,
91  false /*unused*/, pst_entry);
92  } else {
93  patternSequenceTable.accessEntry(pst_entry);
94  }
95  // If the entry existed, this will update the values, if not,
96  // this also sets the values of the entry
97  pst_entry->update(agt_entry);
98  // Free the AGT entry
99  activeGenerationTable.invalidate(&agt_entry);
100  }
101  }
102  }
103 }
104 
105 void
106 STeMSPrefetcher::addToRMOB(Addr sr_addr, Addr pst_addr, unsigned int delta)
107 {
109  rmobHead = (rmobHead + 1) % rmob.size();
110 
111  rmob_entry.srAddress = sr_addr;
112  rmob_entry.pstAddress = pst_addr;
113  rmob_entry.delta = delta;
114  rmob_entry.valid = true;
115 }
116 
117 void
119  std::vector<AddrPriority> &addresses)
120 {
121  if (!pfi.hasPC()) {
122  DPRINTF(HWPrefetch, "Ignoring request with no PC.\n");
123  return;
124  }
125 
126  Addr pc = pfi.getPC();
127  bool is_secure = pfi.isSecure();
128  // Spatial region address
129  Addr sr_addr = pfi.getAddr() / spatialRegionSize;
130  Addr paddr = pfi.getPaddr();
131 
132  // Offset in cachelines within the spatial region
133  Addr sr_offset = (pfi.getAddr() % spatialRegionSize) / blkSize;
134 
135  // Check if any active generation has ended
137 
138  ActiveGenerationTableEntry *agt_entry =
139  activeGenerationTable.findEntry(sr_addr, is_secure);
140  if (agt_entry != nullptr) {
141  // found an entry in the AGT, entry is currently being recorded,
142  // add the offset
143  activeGenerationTable.accessEntry(agt_entry);
144  agt_entry->addOffset(sr_offset);
145  lastTriggerCounter += 1;
146  } else {
147  // Not found, this is the first access (Trigger access)
148 
149  // Add entry to RMOB
150  Addr pst_addr = (pc << spatialRegionSizeBits) + sr_offset;
151  addToRMOB(sr_addr, pst_addr, lastTriggerCounter);
152  // Reset last trigger counter
153  lastTriggerCounter = 0;
154 
155  // allocate a new AGT entry
156  agt_entry = activeGenerationTable.findVictim(sr_addr);
157  assert(agt_entry != nullptr);
158  activeGenerationTable.insertEntry(sr_addr, is_secure, agt_entry);
159  agt_entry->pc = pc;
160  agt_entry->paddress = paddr;
161  agt_entry->addOffset(sr_offset);
162  }
163  // increase the seq Counter for other entries
164  for (auto &agt_e : activeGenerationTable) {
165  if (agt_e.isValid() && agt_entry != &agt_e) {
166  agt_e.seqCounter += 1;
167  }
168  }
169 
170  // Prefetch generation: if this is a miss, search for the most recent
171  // entry in the RMOB, and reconstruct the registered access sequence
172  if (pfi.isCacheMiss()) {
173  for (unsigned int idx = (rmobHead - 1) % rmob.size();
174  idx != rmobHead && rmob[idx].valid;
175  idx = (idx - 1) % rmob.size())
176  {
177  if (rmob[idx].srAddress == sr_addr) {
178  // reconstruct the access sequence
179  reconstructSequence(idx, addresses);
180  break;
181  }
182  }
183  }
184 }
185 
186 void
188  std::vector<AddrPriority> &addresses)
189 {
191  unsigned int idx = 0;
192  // process rmob entries from rmob_idx (most recent with
193  // address = sr_addr) to the last one (rmobHead)
194  for (int i = rmob_idx;
195  i != rmobHead && idx < reconstructionEntries;
196  i = (i + 1) % rmob.size())
197  {
198  reconstruction[idx] = rmob[i].srAddress * spatialRegionSize;
199  unsigned int next_i = (i + 1) % rmob.size();
200  idx += rmob[next_i].delta + 1;
201  }
202  // Now query the PST with the PC of each RMOB entry
203  idx = 0;
204  for (int i = rmob_idx;
205  i != rmobHead && idx < reconstructionEntries;
206  i = (i + 1) % rmob.size())
207  {
208  ActiveGenerationTableEntry *pst_entry =
209  patternSequenceTable.findEntry(rmob[i].pstAddress,
210  false /* unused */);
211  if (pst_entry != nullptr) {
212  patternSequenceTable.accessEntry(pst_entry);
213  for (auto &seq_entry : pst_entry->sequence) {
214  if (seq_entry.counter > 1) {
215  // 2-bit counter: high enough confidence with a
216  // value greater than 1
217  Addr rec_addr = rmob[i].srAddress * spatialRegionSize +
218  seq_entry.offset;
219  unsigned ridx = idx + seq_entry.delta;
220  // Try to use the corresponding position, if it has been
221  // already used, look the surrounding positions
222  if (ridx < reconstructionEntries &&
223  reconstruction[ridx] == MaxAddr) {
224  reconstruction[ridx] = rec_addr;
225  } else if ((ridx + 1) < reconstructionEntries &&
226  reconstruction[ridx + 1] == MaxAddr) {
227  reconstruction[ridx + 1] = rec_addr;
228  } else if ((ridx + 2) < reconstructionEntries &&
229  reconstruction[ridx + 2] == MaxAddr) {
230  reconstruction[ridx + 2] = rec_addr;
231  } else if ((ridx > 0) &&
232  ((ridx - 1) < reconstructionEntries) &&
233  reconstruction[ridx - 1] == MaxAddr) {
234  reconstruction[ridx - 1] = rec_addr;
235  } else if ((ridx > 1) &&
236  ((ridx - 2) < reconstructionEntries) &&
237  reconstruction[ridx - 2] == MaxAddr) {
238  reconstruction[ridx - 2] = rec_addr;
239  }
240  }
241  }
242  }
243  unsigned int next_i = (i + 1) % rmob.size();
244  idx += rmob[next_i].delta + 1;
245  }
246  for (Addr pf_addr : reconstruction) {
247  if (pf_addr != MaxAddr) {
248  addresses.push_back(AddrPriority(pf_addr, 0));
249  }
250  }
251 }
252 
254 STeMSPrefetcherParams::create()
255 {
256  return new STeMSPrefetcher(this);
257 }
#define DPRINTF(x,...)
Definition: trace.hh:229
Data type of the Region Miss Order Buffer entry.
AssociativeSet< ActiveGenerationTableEntry > patternSequenceTable
Pattern Sequence Table (PST)
const unsigned int reconstructionEntries
Number of reconstruction entries.
void checkForActiveGenerationsEnd()
Checks if the active generations have ended.
const Addr MaxAddr
Definition: types.hh:166
Bitfield< 7 > i
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.
bool inCache(Addr addr, bool is_secure) const
Determine if address is in cache.
Definition: base.cc:149
bool isCacheMiss() const
Check if this event comes from a cache miss.
Definition: base.hh:193
bool isSecure() const
Returns true if the address targets the secure memory space.
Definition: base.hh:128
AssociativeSet< ActiveGenerationTableEntry > activeGenerationTable
Active Generation Table (AGT)
STL vector class.
Definition: stl.hh:40
const size_t spatialRegionSizeBits
log_2 of the spatial region size
Addr getAddr() const
Obtains the address value of this Prefetcher address.
Definition: base.hh:119
Bitfield< 4 > pc
Class containing the information needed by the prefetch to train and generate new prefetch requests...
Definition: base.hh:92
std::pair< Addr, int32_t > AddrPriority
Definition: queued.hh:178
void calculatePrefetch(const PrefetchInfo &pfi, std::vector< AddrPriority > &addresses) override
Addr paddress
Physical address of the spatial region.
Addr getPC() const
Returns the program counter that generated this request.
Definition: base.hh:137
void reconstructSequence(unsigned int rmob_idx, std::vector< AddrPriority > &addresses)
Reconstructs a sequence of accesses and generates the prefetch addresses, adding them to the addresse...
bool isPowerOf2(const T &n)
Definition: intmath.hh:146
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition: logging.hh:203
unsigned int delta
Delta within the global miss order sequence.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
std::vector< RegionMissOrderBufferEntry > rmob
Region Miss Order Buffer (RMOB)
unsigned int lastTriggerCounter
Counter to keep the count of accesses between trigger accesses.
const size_t spatialRegionSize
Size of each spatial region.
int floorLog2(unsigned x)
Definition: intmath.hh:61
STeMSPrefetcher(const STeMSPrefetcherParams *p)
Copyright (c) 2019 Metempsy Technology Consulting All rights reserved.
bool inMissQueue(Addr addr, bool is_secure) const
Determine if address is in cache miss queue.
Definition: base.cc:155
Entry data type for the Active Generation Table (AGT) and the Pattern Sequence Table (PST) ...
Addr getPaddr() const
Gets the physical address of the request.
Definition: base.hh:184
unsigned blkSize
The block size of the parent cache.
Definition: base.hh:264
Bitfield< 0 > p
void addToRMOB(Addr sr_addr, Addr pst_addr, unsigned int delta)
Adds an entry to the RMOB.
unsigned int rmobHead
First free position (or older, if it is full) of the RMOB.
Addr pstAddress
Address used to index the PST table, generated using the PC and the offset within the spatial region...
std::vector< SequenceEntry > sequence
Sequence of accesses.
bool hasPC() const
Returns true if the associated program counter is valid.
Definition: base.hh:147

Generated on Fri Feb 28 2020 16:27:01 for gem5 by doxygen 1.8.13