gem5  v20.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
pif.cc
Go to the documentation of this file.
1 
30 
31 #include <utility>
32 
33 #include "debug/HWPrefetch.hh"
35 #include "params/PIFPrefetcher.hh"
36 
37 namespace Prefetcher {
38 
39 PIF::PIF(const PIFPrefetcherParams *p)
40  : Queued(p),
41  precSize(p->prec_spatial_region_bits),
42  succSize(p->succ_spatial_region_bits),
43  maxCompactorEntries(p->compactor_entries),
44  historyBuffer(p->history_buffer_size),
45  index(p->index_assoc, p->index_entries, p->index_indexing_policy,
46  p->index_replacement_policy),
47  streamAddressBuffer(p->stream_address_buffer_entries),
48  listenersPC()
49 {
50 }
51 
53  unsigned int prec_size, unsigned int succ_size)
54 {
55  trigger = addr;
56  prec.resize(prec_size, false);
57  succ.resize(succ_size, false);
58 }
59 
60 Addr
62  unsigned int log_blk_size) const
63 {
64  const Addr target_blk = target >> log_blk_size;
65  const Addr trigger_blk = trigger >> log_blk_size;
66 
67  return target_blk > trigger_blk ?
68  target_blk - trigger_blk : trigger_blk - target_blk;
69 }
70 
71 bool
73  unsigned int log_blk_size, bool update)
74 {
75  Addr blk_distance = distanceFromTrigger(pc, log_blk_size);
76 
77  bool hit = (pc > trigger) ?
78  (succ.size() >= blk_distance) : (prec.size() >= blk_distance);
79  if (hit && update) {
80  if (pc > trigger) {
81  succ[blk_distance - 1] = true;
82  } else if (pc < trigger) {
83  prec[blk_distance - 1] = true;
84  }
85  }
86  return hit;
87 }
88 
89 bool
91  unsigned int log_blk_size) const
92 {
93  Addr blk_distance = distanceFromTrigger(target, log_blk_size);
94  bool hit = false;
95  if (target > trigger) {
96  hit = blk_distance <= succ.size() && succ[blk_distance - 1];
97  } else if (target < trigger) {
98  hit = blk_distance <= prec.size() && succ[blk_distance - 1];
99  } else {
100  hit = true;
101  }
102  return hit;
103 }
104 
105 void
107  std::vector<AddrPriority> &addresses) const
108 {
109  // Calculate the addresses of the instruction blocks that are encoded
110  // by the bit vector and issue prefetch requests for these addresses.
111  // Predictions are made by traversing the bit vector from left to right
112  // as this typically predicts the accesses in the order they will be
113  // issued in the core.
114  const Addr trigger_blk = trigger >> log_blk_size;
115  for (int i = prec.size()-1; i >= 0; i--) {
116  // Address from the preceding blocks to issue a prefetch
117  if (prec[i]) {
118  const Addr prec_addr = (trigger_blk - (i+1)) << log_blk_size;
119  addresses.push_back(AddrPriority(prec_addr, 0));
120  }
121  }
122  for (int i = 0; i < succ.size(); i++) {
123  // Address from the succeding blocks to issue a prefetch
124  if (succ[i]) {
125  const Addr succ_addr = (trigger_blk + (i+1)) << log_blk_size;
126  addresses.push_back(AddrPriority(succ_addr, 0));
127  }
128  }
129 }
130 
131 void
133 {
134  // First access to the prefetcher
135  if (temporalCompactor.size() == 0) {
137  } else {
138  // If the PC of the instruction retired is in the same spatial region
139  // than the last trigger address, update the bit vectors based on the
140  // distance between them
142  // If the PC of the instruction retired is outside the latest spatial
143  // region, check if it matches in any of the regions in the temporal
144  // compactor and update it to the MRU position
145  } else {
146  bool is_in_temporal_compactor = false;
147 
148  // Check if the PC is in the temporal compactor
149  for (auto it = temporalCompactor.begin();
150  it != temporalCompactor.end(); it++)
151  {
152  if (it->inSameSpatialRegion(pc, lBlkSize, false)) {
153  spatialCompactor = (*it);
154  temporalCompactor.erase(it);
155  is_in_temporal_compactor = true;
156  break;
157  }
158  }
159 
160  if (temporalCompactor.size() == maxCompactorEntries) {
161  temporalCompactor.pop_front(); // Discard the LRU entry
162  }
163 
165 
166  // If the compactor entry is neither the spatial or can't be
167  // found in the temporal compactor, reset the spatial compactor
168  // updating the trigger address and resetting the vector bits
169  if (!is_in_temporal_compactor) {
170  // Insert the spatial entry into the history buffer and update
171  // the 'iterator' table to point to the new entry
173 
174  IndexEntry *idx_entry =
175  index.findEntry(spatialCompactor.trigger, false);
176  if (idx_entry != nullptr) {
177  index.accessEntry(idx_entry);
178  } else {
179  idx_entry = index.findVictim(spatialCompactor.trigger);
180  assert(idx_entry != nullptr);
181  index.insertEntry(spatialCompactor.trigger, false,
182  idx_entry);
183  }
184  idx_entry->historyIt =
186 
187  // Reset the spatial compactor fields with the new address
189  }
190  }
191  }
192 }
193 
194 void
196  std::vector<AddrPriority> &addresses)
197 {
198  const Addr addr = pfi.getAddr();
199 
200  // First check if the access has been prefetched, this is done by
201  // comparing the access against the active Stream Address Buffers
202  for (auto &sabEntry : streamAddressBuffer) {
203  if (sabEntry->hasAddress(addr, lBlkSize)) {
204  sabEntry++;
205  sabEntry->getPredictedAddresses(lBlkSize, addresses);
206  // We are done
207  return;
208  }
209  }
210 
211  // Check if a valid entry in the 'index' table is found and allocate a new
212  // active prediction stream
213  IndexEntry *idx_entry = index.findEntry(addr, /* unused */ false);
214 
215  if (idx_entry != nullptr) {
216  index.accessEntry(idx_entry);
217  // Trigger address from the 'index' table and index to the history
218  // buffer
219  auto entry = idx_entry->historyIt;
220 
221  // Track the block in the Stream Address Buffer
222  streamAddressBuffer.push_back(entry);
223 
224  entry->getPredictedAddresses(lBlkSize, addresses);
225  }
226 }
227 
228 void
230 {
231  parent.notifyRetiredInst(pc);
232 }
233 
234 void
236 {
237  ProbeManager *pm(obj->getProbeManager());
238  listenersPC.push_back(new PrefetchListenerPC(*this, pm, name));
239 }
240 
241 } // namespace Prefetcher
242 
244 PIFPrefetcherParams::create()
245 {
246  return new Prefetcher::PIF(this);
247 }
Probe Listener to handle probe events from the CPU.
Definition: pif.hh:159
std::pair< Addr, int32_t > AddrPriority
Definition: queued.hh:178
Bitfield< 30, 0 > index
void getPredictedAddresses(unsigned int log_blk_size, std::vector< AddrPriority > &addresses) const
Fills the provided vector with the predicted addresses using the recorded bit vectors of the entry...
Definition: pif.cc:106
Bitfield< 7 > i
CircularQueue< HistoryBuffer::iterator > streamAddressBuffer
A Stream Address Buffer (SAB) tracks a window of consecutive spatial regions.
Definition: pif.hh:148
uint32_t tail() const
void addEventProbeRetiredInsts(SimObject *obj, const char *name)
Add a SimObject and a probe name to monitor the retired instructions.
Definition: pif.cc:235
const unsigned int precSize
Number of preceding and subsequent spatial addresses to compact.
Definition: pif.hh:55
ip6_addr_t addr
Definition: inet.hh:330
iterator getIterator(size_t idx)
Return an iterator to an index in the vector.
ProbeManager is a conduit class that lives on each SimObject, and is used to match up probe listeners...
Definition: probe.hh:150
Class containing the information needed by the prefetch to train and generate new prefetch requests...
Definition: base.hh:91
CompactorEntry spatialCompactor
Definition: pif.hh:122
STL vector class.
Definition: stl.hh:37
void push_back(typename Base::value_type val)
Pushes an element at the end of the queue.
const unsigned int maxCompactorEntries
Number of entries used for the temporal compactor.
Definition: pif.hh:58
bool hasAddress(Addr target, unsigned int log_blk_size) const
Checks if the provided address is contained in this spatial region and if its corresponding bit vecto...
Definition: pif.cc:90
std::vector< PrefetchListenerPC * > listenersPC
Array of probe listeners.
Definition: pif.hh:172
Bitfield< 4 > pc
void notify(const Addr &pc) override
Definition: pif.cc:229
const unsigned int succSize
Definition: pif.hh:56
bool inSameSpatialRegion(Addr addr, unsigned int log_blk_size, bool update)
Checks if a given address is in the same defined spatial region as the compactor entry.
Definition: pif.cc:72
Addr getAddr() const
Obtains the address value of this Prefetcher address.
Definition: base.hh:118
HistoryBuffer historyBuffer
Definition: pif.hh:130
unsigned lBlkSize
log_2(block size of the parent cache).
Definition: base.hh:266
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:140
PIF(const PIFPrefetcherParams *p)
Definition: pif.cc:39
Addr distanceFromTrigger(Addr addr, unsigned int log_blk_size) const
Computes the distance, in cache blocks, from an address to the trigger of the entry.
Definition: pif.cc:61
ProbeManager * getProbeManager()
Get the probe manager for this object.
Definition: sim_object.cc:117
void notifyRetiredInst(const Addr pc)
Updates the prefetcher structures upon an instruction retired.
Definition: pif.cc:132
HistoryBuffer::iterator historyIt
Definition: pif.hh:134
virtual const std::string name() const
Definition: sim_object.hh:129
void calculatePrefetch(const PrefetchInfo &pfi, std::vector< AddrPriority > &addresses)
Definition: pif.cc:195
std::deque< CompactorEntry > temporalCompactor
Definition: pif.hh:123
AssociativeSet< IndexEntry > index
The index table is a small cache-like structure that facilitates fast search of the history buffer...
Definition: pif.hh:140
The compactor tracks retired instructions addresses, leveraging the spatial and temporal locality amo...
Definition: pif.hh:74
Bitfield< 21 > trigger
Definition: intmessage.hh:48
Copyright (c) 2018 Metempsy Technology Consulting All rights reserved.
Definition: base.hh:78
Bitfield< 0 > p
void update() const
Align cycle and tick to the next clock edge if not already done.
Abstract superclass for simulation objects.
Definition: sim_object.hh:93

Generated on Thu May 28 2020 16:21:34 for gem5 by doxygen 1.8.13