gem5  v20.1.0.0
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] = true;
82  } else if (pc < trigger) {
83  prec[blk_distance] = 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];
97  } else if (target < trigger) {
98  hit = blk_distance < prec.size() && prec[blk_distance];
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) {
138  } else {
139  // If the PC of the instruction retired is in the same spatial region
140  // than the last trigger address, update the bit vectors based on the
141  // distance between them
143  // If the PC of the instruction retired is outside the latest spatial
144  // region, check if it matches in any of the regions in the temporal
145  // compactor and update it to the MRU position
146  } else {
147  bool is_in_temporal_compactor = false;
148 
149  // Check if the PC is in the temporal compactor
150  for (auto it = temporalCompactor.begin();
151  it != temporalCompactor.end(); it++)
152  {
153  if (it->inSameSpatialRegion(pc, lBlkSize, false)) {
154  spatialCompactor = (*it);
155  temporalCompactor.erase(it);
156  is_in_temporal_compactor = true;
157  break;
158  }
159  }
160 
161  if (temporalCompactor.size() == maxCompactorEntries) {
162  temporalCompactor.pop_front(); // Discard the LRU entry
163  }
164 
166 
167  // If the compactor entry is neither the spatial or can't be
168  // found in the temporal compactor, reset the spatial compactor
169  // updating the trigger address and resetting the vector bits
170  if (!is_in_temporal_compactor) {
171  // Insert the spatial entry into the history buffer and update
172  // the 'iterator' table to point to the new entry
174 
175  IndexEntry *idx_entry =
176  index.findEntry(spatialCompactor.trigger, false);
177  if (idx_entry != nullptr) {
178  index.accessEntry(idx_entry);
179  } else {
180  idx_entry = index.findVictim(spatialCompactor.trigger);
181  assert(idx_entry != nullptr);
182  index.insertEntry(spatialCompactor.trigger, false,
183  idx_entry);
184  }
185  idx_entry->historyIt =
187 
188  // Reset the spatial compactor fields with the new address
190  }
191  }
192  }
193 }
194 
195 void
197  std::vector<AddrPriority> &addresses)
198 {
199  if (!pfi.hasPC()) {
200  return;
201  }
202 
203  const Addr pc = pfi.getPC();
204 
205  // First check if the access has been prefetched, this is done by
206  // comparing the access against the active Stream Address Buffers
207  for (auto &sabEntry : streamAddressBuffer) {
208  if (sabEntry->hasAddress(pc, lBlkSize)) {
209  sabEntry++;
210  sabEntry->getPredictedAddresses(lBlkSize, addresses);
211  // We are done
212  return;
213  }
214  }
215 
216  // Check if a valid entry in the 'index' table is found and allocate a new
217  // active prediction stream
218  IndexEntry *idx_entry = index.findEntry(pc, /* unused */ false);
219 
220  if (idx_entry != nullptr) {
221  index.accessEntry(idx_entry);
222  // Trigger address from the 'index' table and index to the history
223  // buffer
224  auto entry = idx_entry->historyIt;
225 
226  // Track the block in the Stream Address Buffer
227  streamAddressBuffer.push_back(entry);
228 
229  entry->getPredictedAddresses(lBlkSize, addresses);
230  }
231 }
232 
233 void
235 {
236  parent.notifyRetiredInst(pc);
237 }
238 
239 void
241 {
242  ProbeManager *pm(obj->getProbeManager());
243  listenersPC.push_back(new PrefetchListenerPC(*this, pm, name));
244 }
245 
246 } // namespace Prefetcher
247 
249 PIFPrefetcherParams::create()
250 {
251  return new Prefetcher::PIF(this);
252 }
associative_set_impl.hh
Prefetcher::Queued::AddrPriority
std::pair< Addr, int32_t > AddrPriority
Definition: queued.hh:182
MipsISA::index
Bitfield< 30, 0 > index
Definition: pra_constants.hh:44
Prefetcher::PIF::CompactorEntry::hasAddress
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
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
CircularQueue::getIterator
iterator getIterator(size_t idx)
Return an iterator to an index in the vector.
Definition: circular_queue.hh:812
Prefetcher::Base::PrefetchInfo::getPC
Addr getPC() const
Returns the program counter that generated this request.
Definition: base.hh:135
Prefetcher::PIF::PrefetchListenerPC
Probe Listener to handle probe events from the CPU.
Definition: pif.hh:159
Prefetcher::PIF::CompactorEntry::CompactorEntry
CompactorEntry()
Definition: pif.hh:78
Prefetcher::PIF::maxCompactorEntries
const unsigned int maxCompactorEntries
Number of entries used for the temporal compactor.
Definition: pif.hh:58
Prefetcher::PIF::precSize
const unsigned int precSize
Number of preceding and subsequent spatial addresses to compact.
Definition: pif.hh:55
std::vector
STL vector class.
Definition: stl.hh:37
Prefetcher::PIF::streamAddressBuffer
CircularQueue< HistoryBuffer::iterator > streamAddressBuffer
A Stream Address Buffer (SAB) tracks a window of consecutive spatial regions.
Definition: pif.hh:148
Prefetcher::PIF::addEventProbeRetiredInsts
void addEventProbeRetiredInsts(SimObject *obj, const char *name)
Add a SimObject and a probe name to monitor the retired instructions.
Definition: pif.cc:240
Prefetcher::PIF::succSize
const unsigned int succSize
Definition: pif.hh:56
Prefetcher::PIF::listenersPC
std::vector< PrefetchListenerPC * > listenersPC
Array of probe listeners.
Definition: pif.hh:172
Clocked::update
void update() const
Align cycle and tick to the next clock edge if not already done.
Definition: clocked_object.hh:76
Prefetcher::PIF::IndexEntry::historyIt
HistoryBuffer::iterator historyIt
Definition: pif.hh:134
Prefetcher::PIF::CompactorEntry::succ
std::vector< bool > succ
Definition: pif.hh:77
Prefetcher::PIF
Definition: pif.hh:51
Prefetcher::PIF::spatialCompactor
CompactorEntry spatialCompactor
Definition: pif.hh:122
Prefetcher::Base::lBlkSize
unsigned lBlkSize
log_2(block size of the parent cache).
Definition: base.hh:265
MipsISA::pc
Bitfield< 4 > pc
Definition: pra_constants.hh:240
Prefetcher::PIF::CompactorEntry::prec
std::vector< bool > prec
Definition: pif.hh:76
Prefetcher
Copyright (c) 2018 Metempsy Technology Consulting All rights reserved.
Definition: base.hh:78
Prefetcher::PIF::PIF
PIF(const PIFPrefetcherParams *p)
Definition: pif.cc:39
Prefetcher::PIF::index
AssociativeSet< IndexEntry > index
The index table is a small cache-like structure that facilitates fast search of the history buffer.
Definition: pif.hh:140
Prefetcher::PIF::historyBuffer
HistoryBuffer historyBuffer
Definition: pif.hh:130
CircularQueue::push_back
void push_back(typename Base::value_type val)
Pushes an element at the end of the queue.
Definition: circular_queue.hh:692
Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
Prefetcher::Queued
Definition: queued.hh:54
SimObject::getProbeManager
ProbeManager * getProbeManager()
Get the probe manager for this object.
Definition: sim_object.cc:117
pif.hh
Prefetcher::PIF::calculatePrefetch
void calculatePrefetch(const PrefetchInfo &pfi, std::vector< AddrPriority > &addresses)
Definition: pif.cc:196
SimObject::name
virtual const std::string name() const
Definition: sim_object.hh:133
Prefetcher::PIF::PrefetchListenerPC::notify
void notify(const Addr &pc) override
Definition: pif.cc:234
ProbeManager
ProbeManager is a conduit class that lives on each SimObject, and is used to match up probe listeners...
Definition: probe.hh:150
Prefetcher::PIF::CompactorEntry::distanceFromTrigger
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
Prefetcher::PIF::IndexEntry
Definition: pif.hh:132
Prefetcher::PIF::temporalCompactor
std::deque< CompactorEntry > temporalCompactor
Definition: pif.hh:123
addr
ip6_addr_t addr
Definition: inet.hh:423
Prefetcher::Base::PrefetchInfo
Class containing the information needed by the prefetch to train and generate new prefetch requests.
Definition: base.hh:90
Prefetcher::PIF::CompactorEntry
The compactor tracks retired instructions addresses, leveraging the spatial and temporal locality amo...
Definition: pif.hh:74
Prefetcher::PIF::CompactorEntry::inSameSpatialRegion
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
Prefetcher::PIF::notifyRetiredInst
void notifyRetiredInst(const Addr pc)
Updates the prefetcher structures upon an instruction retired.
Definition: pif.cc:132
MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:323
Prefetcher::PIF::CompactorEntry::trigger
Addr trigger
Definition: pif.hh:75
CircularQueue::tail
uint32_t tail() const
Definition: circular_queue.hh:623
X86ISA::trigger
Bitfield< 21 > trigger
Definition: intmessage.hh:48
Prefetcher::PIF::CompactorEntry::getPredictedAddresses
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
Prefetcher::Base::PrefetchInfo::hasPC
bool hasPC() const
Returns true if the associated program counter is valid.
Definition: base.hh:145
SimObject
Abstract superclass for simulation objects.
Definition: sim_object.hh:92

Generated on Wed Sep 30 2020 14:02:12 for gem5 by doxygen 1.8.17