gem5  v19.0.0.0
access_map_pattern_matching.cc
Go to the documentation of this file.
1 
32 
33 #include "debug/HWPrefetch.hh"
35 #include "params/AMPMPrefetcher.hh"
36 #include "params/AccessMapPatternMatching.hh"
37 
39  const AccessMapPatternMatchingParams *p)
40  : ClockedObject(p), blkSize(p->block_size), limitStride(p->limit_stride),
41  startDegree(p->start_degree), hotZoneSize(p->hot_zone_size),
42  highCoverageThreshold(p->high_coverage_threshold),
43  lowCoverageThreshold(p->low_coverage_threshold),
44  highAccuracyThreshold(p->high_accuracy_threshold),
45  lowAccuracyThreshold(p->low_accuracy_threshold),
46  highCacheHitThreshold(p->high_cache_hit_threshold),
47  lowCacheHitThreshold(p->low_cache_hit_threshold),
48  epochCycles(p->epoch_cycles),
49  offChipMemoryLatency(p->offchip_memory_latency),
50  accessMapTable(p->access_map_table_assoc, p->access_map_table_entries,
51  p->access_map_table_indexing_policy,
52  p->access_map_table_replacement_policy,
53  AccessMapEntry(hotZoneSize / blkSize)),
54  numGoodPrefetches(0), numTotalPrefetches(0), numRawCacheMisses(0),
55  numRawCacheHits(0), degree(startDegree), usefulDegree(startDegree),
56  epochEvent([this]{ processEpochEvent(); }, name())
57 {
59  "the hot zone size must be a power of 2");
60 }
61 
62 void
64 {
66 }
67 
68 void
70 {
72  double prefetch_accuracy =
73  ((double) numGoodPrefetches) / ((double) numTotalPrefetches);
74  double prefetch_coverage =
75  ((double) numGoodPrefetches) / ((double) numRawCacheMisses);
76  double cache_hit_ratio = ((double) numRawCacheHits) /
77  ((double) (numRawCacheHits + numRawCacheMisses));
78  double num_requests = (double) (numRawCacheMisses - numGoodPrefetches +
79  numTotalPrefetches);
80  double memory_bandwidth = num_requests * offChipMemoryLatency /
82 
83  if (prefetch_coverage > highCoverageThreshold &&
84  (prefetch_accuracy > highAccuracyThreshold ||
85  cache_hit_ratio < lowCacheHitThreshold)) {
86  usefulDegree += 1;
87  } else if ((prefetch_coverage < lowCoverageThreshold &&
88  (prefetch_accuracy < lowAccuracyThreshold ||
89  cache_hit_ratio > highCacheHitThreshold)) ||
90  (prefetch_accuracy < lowAccuracyThreshold &&
91  cache_hit_ratio > highCacheHitThreshold)) {
92  usefulDegree -= 1;
93  }
94  degree = std::min((unsigned) memory_bandwidth, usefulDegree);
95  // reset epoch stats
96  numGoodPrefetches = 0.0;
97  numTotalPrefetches = 0.0;
98  numRawCacheMisses = 0.0;
99  numRawCacheHits = 0.0;
100 }
101 
104  bool is_secure)
105 {
106  AccessMapEntry *am_entry = accessMapTable.findEntry(am_addr, is_secure);
107  if (am_entry != nullptr) {
108  accessMapTable.accessEntry(am_entry);
109  } else {
110  am_entry = accessMapTable.findVictim(am_addr);
111  assert(am_entry != nullptr);
112 
113  accessMapTable.insertEntry(am_addr, is_secure, am_entry);
114  }
115  return am_entry;
116 }
117 
118 void
120  Addr block, enum AccessMapState state)
121 {
122  enum AccessMapState old = entry.states[block];
123  entry.states[block] = state;
124 
125  //do not update stats when initializing
126  if (state == AM_INIT) return;
127 
128  switch (old) {
129  case AM_INIT:
130  if (state == AM_PREFETCH) {
131  numTotalPrefetches += 1;
132  } else if (state == AM_ACCESS) {
133  numRawCacheMisses += 1;
134  }
135  break;
136  case AM_PREFETCH:
137  if (state == AM_ACCESS) {
138  numGoodPrefetches += 1;
139  numRawCacheMisses += 1;
140  }
141  break;
142  case AM_ACCESS:
143  if (state == AM_ACCESS) {
144  numRawCacheHits += 1;
145  }
146  break;
147  default:
148  panic("Impossible path\n");
149  break;
150  }
151 }
152 
153 void
155  const BasePrefetcher::PrefetchInfo &pfi,
157 {
158  assert(addresses.empty());
159 
160  bool is_secure = pfi.isSecure();
161  Addr am_addr = pfi.getAddr() / hotZoneSize;
162  Addr current_block = (pfi.getAddr() % hotZoneSize) / blkSize;
163  uint64_t lines_per_zone = hotZoneSize / blkSize;
164 
165  // Get the entries of the curent block (am_addr), the previous, and the
166  // following ones
167  AccessMapEntry *am_entry_curr = getAccessMapEntry(am_addr, is_secure);
168  AccessMapEntry *am_entry_prev = (am_addr > 0) ?
169  getAccessMapEntry(am_addr-1, is_secure) : nullptr;
170  AccessMapEntry *am_entry_next = (am_addr < (MaxAddr/hotZoneSize)) ?
171  getAccessMapEntry(am_addr+1, is_secure) : nullptr;
172  assert(am_entry_curr != am_entry_prev);
173  assert(am_entry_curr != am_entry_next);
174  assert(am_entry_prev != am_entry_next);
175  assert(am_entry_curr != nullptr);
176 
177  //Mark the current access as Accessed
178  setEntryState(*am_entry_curr, current_block, AM_ACCESS);
179 
185  std::vector<AccessMapState> states(3 * lines_per_zone);
186  for (unsigned idx = 0; idx < lines_per_zone; idx += 1) {
187  states[idx] =
188  am_entry_prev != nullptr ? am_entry_prev->states[idx] : AM_INVALID;
189  states[idx + lines_per_zone] = am_entry_curr->states[idx];
190  states[idx + 2 * lines_per_zone] =
191  am_entry_next != nullptr ? am_entry_next->states[idx] : AM_INVALID;
192  }
193 
200  // index of the current_block in the new vector
201  Addr states_current_block = current_block + lines_per_zone;
202  // consider strides 1..lines_per_zone/2
203  int max_stride = limitStride == 0 ? lines_per_zone / 2 : limitStride + 1;
204  for (int stride = 1; stride < max_stride; stride += 1) {
205  // Test accessed positive strides
206  if (checkCandidate(states, states_current_block, stride)) {
207  // candidate found, current_block - stride
208  Addr pf_addr;
209  if (stride > current_block) {
210  // The index (current_block - stride) falls in the range of
211  // the previous zone (am_entry_prev), adjust the address
212  // accordingly
213  Addr blk = states_current_block - stride;
214  pf_addr = (am_addr - 1) * hotZoneSize + blk * blkSize;
215  setEntryState(*am_entry_prev, blk, AM_PREFETCH);
216  } else {
217  // The index (current_block - stride) falls within
218  // am_entry_curr
219  Addr blk = current_block - stride;
220  pf_addr = am_addr * hotZoneSize + blk * blkSize;
221  setEntryState(*am_entry_curr, blk, AM_PREFETCH);
222  }
223  addresses.push_back(QueuedPrefetcher::AddrPriority(pf_addr, 0));
224  if (addresses.size() == degree) {
225  break;
226  }
227  }
228 
229  // Test accessed negative strides
230  if (checkCandidate(states, states_current_block, -stride)) {
231  // candidate found, current_block + stride
232  Addr pf_addr;
233  if (current_block + stride >= lines_per_zone) {
234  // The index (current_block + stride) falls in the range of
235  // the next zone (am_entry_next), adjust the address
236  // accordingly
237  Addr blk = (states_current_block + stride) % lines_per_zone;
238  pf_addr = (am_addr + 1) * hotZoneSize + blk * blkSize;
239  setEntryState(*am_entry_next, blk, AM_PREFETCH);
240  } else {
241  // The index (current_block + stride) falls within
242  // am_entry_curr
243  Addr blk = current_block + stride;
244  pf_addr = am_addr * hotZoneSize + blk * blkSize;
245  setEntryState(*am_entry_curr, blk, AM_PREFETCH);
246  }
247  addresses.push_back(QueuedPrefetcher::AddrPriority(pf_addr, 0));
248  if (addresses.size() == degree) {
249  break;
250  }
251  }
252  }
253 }
254 
256 AccessMapPatternMatchingParams::create()
257 {
258  return new AccessMapPatternMatching(this);
259 }
260 
261 AMPMPrefetcher::AMPMPrefetcher(const AMPMPrefetcherParams *p)
262  : QueuedPrefetcher(p), ampm(*p->ampm)
263 {
264 }
265 
266 void
268  std::vector<AddrPriority> &addresses)
269 {
270  ampm.calculatePrefetch(pfi, addresses);
271 }
272 
274 AMPMPrefetcherParams::create()
275 {
276  return new AMPMPrefetcher(this);
277 }
const Tick offChipMemoryLatency
Off chip memory latency to use for the epoch bandwidth calculation.
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:167
const double highAccuracyThreshold
A prefetch accuracy factor bigger than this is considered high.
void processEpochEvent()
This event constitues the epoch of the statistics that keep track of the prefetcher accuracy...
const Addr MaxAddr
Definition: types.hh:166
STL pair class.
Definition: stl.hh:61
std::vector< AccessMapState > states
vector containing the state of the cachelines in this zone
Bitfield< 21, 20 > stride
AccessMapPatternMatching & ampm
void startup() override
startup() is the final initialization call before simulation.
bool isSecure() const
Returns true if the address targets the secure memory space.
Definition: base.hh:128
const double lowCacheHitThreshold
A cache hit ratio smaller than this is considered low.
uint64_t numTotalPrefetches
Number of prefetches issued.
const double highCoverageThreshold
A prefetch coverage factor bigger than this is considered high.
unsigned usefulDegree
Current useful degree.
const double lowCoverageThreshold
A prefetch coverage factor smaller than this is considered low.
STL vector class.
Definition: stl.hh:40
AccessMapEntry * getAccessMapEntry(Addr am_addr, bool is_secure)
Obtain an AccessMapEntry from the AccessMapTable, if the entry is not found a new one is initialized ...
uint64_t numGoodPrefetches
Number of good prefetches.
void calculatePrefetch(const BasePrefetcher::PrefetchInfo &pfi, std::vector< QueuedPrefetcher::AddrPriority > &addresses)
Addr getAddr() const
Obtains the address value of this Prefetcher address.
Definition: base.hh:119
void calculatePrefetch(const PrefetchInfo &pfi, std::vector< AddrPriority > &addresses) override
uint64_t numRawCacheHits
Number of raw cache hits.
Class containing the information needed by the prefetch to train and generate new prefetch requests...
Definition: base.hh:92
AccessMapState
Data type representing the state of a cacheline in the access map.
The ClockedObject class extends the SimObject with a clock and accessor functions to relate ticks to ...
AssociativeSet< AccessMapEntry > accessMapTable
Access map table.
AMPMPrefetcher(const AMPMPrefetcherParams *p)
const unsigned limitStride
Limit the stride checking to -limitStride/+limitStride.
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
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
virtual const std::string name() const
Definition: sim_object.hh:120
Tick clockEdge(Cycles cycles=Cycles(0)) const
Determine the tick when a cycle begins, by default the current one, but the argument also enables the...
AccessMapPatternMatching(const AccessMapPatternMatchingParams *p)
Copyright (c) 2018 Metempsy Technology Consulting All rights reserved.
const double highCacheHitThreshold
A cache hit ratio bigger than this is considered high.
void schedule(Event &event, Tick when)
Definition: eventq.hh:744
const uint64_t hotZoneSize
Amount of memory covered by a hot zone.
const unsigned blkSize
Cacheline size used by the prefetcher using this object.
const double lowAccuracyThreshold
A prefetch accuracy factor smaller than this is considered low.
Bitfield< 0 > p
uint64_t numRawCacheMisses
Number of raw cache misses.
const Cycles epochCycles
Cycles in an epoch period.
void setEntryState(AccessMapEntry &entry, Addr block, enum AccessMapState state)
Updates the state of a block within an AccessMapEntry, also updates the prefetcher metrics...
bool checkCandidate(std::vector< AccessMapState > const &states, Addr current, int stride) const
Given a target cacheline, this function checks if the cachelines that follow the provided stride have...

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