gem5  v20.1.0.0
access_map_pattern_matching.cc
Go to the documentation of this file.
1 
30 
31 #include "debug/HWPrefetch.hh"
33 #include "params/AMPMPrefetcher.hh"
34 #include "params/AccessMapPatternMatching.hh"
35 
36 namespace Prefetcher {
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 {
58  fatal_if(!isPowerOf2(hotZoneSize),
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 +
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
156 {
157  assert(addresses.empty());
158 
159  bool is_secure = pfi.isSecure();
160  Addr am_addr = pfi.getAddr() / hotZoneSize;
161  Addr current_block = (pfi.getAddr() % hotZoneSize) / blkSize;
162  uint64_t lines_per_zone = hotZoneSize / blkSize;
163 
164  // Get the entries of the curent block (am_addr), the previous, and the
165  // following ones
166  AccessMapEntry *am_entry_curr = getAccessMapEntry(am_addr, is_secure);
167  AccessMapEntry *am_entry_prev = (am_addr > 0) ?
168  getAccessMapEntry(am_addr-1, is_secure) : nullptr;
169  AccessMapEntry *am_entry_next = (am_addr < (MaxAddr/hotZoneSize)) ?
170  getAccessMapEntry(am_addr+1, is_secure) : nullptr;
171  assert(am_entry_curr != am_entry_prev);
172  assert(am_entry_curr != am_entry_next);
173  assert(am_entry_prev != am_entry_next);
174  assert(am_entry_curr != nullptr);
175 
176  //Mark the current access as Accessed
177  setEntryState(*am_entry_curr, current_block, AM_ACCESS);
178 
184  std::vector<AccessMapState> states(3 * lines_per_zone);
185  for (unsigned idx = 0; idx < lines_per_zone; idx += 1) {
186  states[idx] =
187  am_entry_prev != nullptr ? am_entry_prev->states[idx] : AM_INVALID;
188  states[idx + lines_per_zone] = am_entry_curr->states[idx];
189  states[idx + 2 * lines_per_zone] =
190  am_entry_next != nullptr ? am_entry_next->states[idx] : AM_INVALID;
191  }
192 
199  // index of the current_block in the new vector
200  Addr states_current_block = current_block + lines_per_zone;
201  // consider strides 1..lines_per_zone/2
202  int max_stride = limitStride == 0 ? lines_per_zone / 2 : limitStride + 1;
203  for (int stride = 1; stride < max_stride; stride += 1) {
204  // Test accessed positive strides
205  if (checkCandidate(states, states_current_block, stride)) {
206  // candidate found, current_block - stride
207  Addr pf_addr;
208  if (stride > current_block) {
209  // The index (current_block - stride) falls in the range of
210  // the previous zone (am_entry_prev), adjust the address
211  // accordingly
212  Addr blk = states_current_block - stride;
213  pf_addr = (am_addr - 1) * hotZoneSize + blk * blkSize;
214  setEntryState(*am_entry_prev, blk, AM_PREFETCH);
215  } else {
216  // The index (current_block - stride) falls within
217  // am_entry_curr
218  Addr blk = current_block - stride;
219  pf_addr = am_addr * hotZoneSize + blk * blkSize;
220  setEntryState(*am_entry_curr, blk, AM_PREFETCH);
221  }
222  addresses.push_back(Queued::AddrPriority(pf_addr, 0));
223  if (addresses.size() == degree) {
224  break;
225  }
226  }
227 
228  // Test accessed negative strides
229  if (checkCandidate(states, states_current_block, -stride)) {
230  // candidate found, current_block + stride
231  Addr pf_addr;
232  if (current_block + stride >= lines_per_zone) {
233  // The index (current_block + stride) falls in the range of
234  // the next zone (am_entry_next), adjust the address
235  // accordingly
236  Addr blk = (states_current_block + stride) % lines_per_zone;
237  pf_addr = (am_addr + 1) * hotZoneSize + blk * blkSize;
238  setEntryState(*am_entry_next, blk, AM_PREFETCH);
239  } else {
240  // The index (current_block + stride) falls within
241  // am_entry_curr
242  Addr blk = current_block + stride;
243  pf_addr = am_addr * hotZoneSize + blk * blkSize;
244  setEntryState(*am_entry_curr, blk, AM_PREFETCH);
245  }
246  addresses.push_back(Queued::AddrPriority(pf_addr, 0));
247  if (addresses.size() == degree) {
248  break;
249  }
250  }
251  }
252 }
253 
254 AMPM::AMPM(const AMPMPrefetcherParams *p)
255  : Queued(p), ampm(*p->ampm)
256 {
257 }
258 
259 void
261  std::vector<AddrPriority> &addresses)
262 {
263  ampm.calculatePrefetch(pfi, addresses);
264 }
265 
266 } // namespace Prefetcher
267 
269 AccessMapPatternMatchingParams::create()
270 {
271  return new Prefetcher::AccessMapPatternMatching(this);
272 }
273 
275 AMPMPrefetcherParams::create()
276 {
277  return new Prefetcher::AMPM(this);
278 }
associative_set_impl.hh
Prefetcher::AccessMapPatternMatching::lowCoverageThreshold
const double lowCoverageThreshold
A prefetch coverage factor smaller than this is considered low.
Definition: access_map_pattern_matching.hh:64
Prefetcher::AccessMapPatternMatching::numTotalPrefetches
uint64_t numTotalPrefetches
Number of prefetches issued.
Definition: access_map_pattern_matching.hh:119
Prefetcher::AccessMapPatternMatching::numGoodPrefetches
uint64_t numGoodPrefetches
Number of good prefetches.
Definition: access_map_pattern_matching.hh:114
Prefetcher::AccessMapPatternMatching::AM_INVALID
@ AM_INVALID
Definition: access_map_pattern_matching.hh:84
Prefetcher::AccessMapPatternMatching::AM_INIT
@ AM_INIT
Definition: access_map_pattern_matching.hh:81
Prefetcher::AccessMapPatternMatching::calculatePrefetch
void calculatePrefetch(const Base::PrefetchInfo &pfi, std::vector< Queued::AddrPriority > &addresses)
Definition: access_map_pattern_matching.cc:154
Prefetcher::AMPM::AMPM
AMPM(const AMPMPrefetcherParams *p)
Definition: access_map_pattern_matching.cc:254
Prefetcher::AccessMapPatternMatching::processEpochEvent
void processEpochEvent()
This event constitues the epoch of the statistics that keep track of the prefetcher accuracy,...
Definition: access_map_pattern_matching.cc:69
Prefetcher::AccessMapPatternMatching::offChipMemoryLatency
const Tick offChipMemoryLatency
Off chip memory latency to use for the epoch bandwidth calculation.
Definition: access_map_pattern_matching.hh:76
Prefetcher::AccessMapPatternMatching::AccessMapState
AccessMapState
Data type representing the state of a cacheline in the access map.
Definition: access_map_pattern_matching.hh:79
Prefetcher::AccessMapPatternMatching::startup
void startup() override
startup() is the final initialization call before simulation.
Definition: access_map_pattern_matching.cc:63
Prefetcher::AccessMapPatternMatching::AccessMapEntry
AccessMapEntry data type.
Definition: access_map_pattern_matching.hh:88
Prefetcher::AMPM::ampm
AccessMapPatternMatching & ampm
Definition: access_map_pattern_matching.hh:194
access_map_pattern_matching.hh
Prefetcher::AccessMapPatternMatching::epochCycles
const Cycles epochCycles
Cycles in an epoch period.
Definition: access_map_pattern_matching.hh:74
Prefetcher::AccessMapPatternMatching::numRawCacheMisses
uint64_t numRawCacheMisses
Number of raw cache misses.
Definition: access_map_pattern_matching.hh:124
Prefetcher::AccessMapPatternMatching::AccessMapPatternMatching
AccessMapPatternMatching(const AccessMapPatternMatchingParams *p)
Definition: access_map_pattern_matching.cc:38
Prefetcher::AccessMapPatternMatching::degree
unsigned degree
Current degree.
Definition: access_map_pattern_matching.hh:131
Prefetcher::AccessMapPatternMatching::getAccessMapEntry
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 ...
Definition: access_map_pattern_matching.cc:103
Prefetcher::AccessMapPatternMatching::highCacheHitThreshold
const double highCacheHitThreshold
A cache hit ratio bigger than this is considered high.
Definition: access_map_pattern_matching.hh:70
std::vector
STL vector class.
Definition: stl.hh:37
Prefetcher::AccessMapPatternMatching::lowAccuracyThreshold
const double lowAccuracyThreshold
A prefetch accuracy factor smaller than this is considered low.
Definition: access_map_pattern_matching.hh:68
Prefetcher::AMPM::calculatePrefetch
void calculatePrefetch(const PrefetchInfo &pfi, std::vector< AddrPriority > &addresses) override
Definition: access_map_pattern_matching.cc:260
MaxAddr
const Addr MaxAddr
Definition: types.hh:166
ClockedObject
The ClockedObject class extends the SimObject with a clock and accessor functions to relate ticks to ...
Definition: clocked_object.hh:231
EventManager::schedule
void schedule(Event &event, Tick when)
Definition: eventq.hh:1005
Prefetcher::AccessMapPatternMatching::highCoverageThreshold
const double highCoverageThreshold
A prefetch coverage factor bigger than this is considered high.
Definition: access_map_pattern_matching.hh:62
Prefetcher::AccessMapPatternMatching::AM_ACCESS
@ AM_ACCESS
Definition: access_map_pattern_matching.hh:83
Prefetcher::AccessMapPatternMatching::numRawCacheHits
uint64_t numRawCacheHits
Number of raw cache hits.
Definition: access_map_pattern_matching.hh:129
Prefetcher::AccessMapPatternMatching::limitStride
const unsigned limitStride
Limit the stride checking to -limitStride/+limitStride.
Definition: access_map_pattern_matching.hh:56
Prefetcher::AccessMapPatternMatching::highAccuracyThreshold
const double highAccuracyThreshold
A prefetch accuracy factor bigger than this is considered high.
Definition: access_map_pattern_matching.hh:66
Clocked::clockEdge
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...
Definition: clocked_object.hh:174
Prefetcher
Copyright (c) 2018 Metempsy Technology Consulting All rights reserved.
Definition: base.hh:78
Prefetcher::AMPM
Definition: access_map_pattern_matching.hh:192
std::pair
STL pair class.
Definition: stl.hh:58
Prefetcher::AccessMapPatternMatching::checkCandidate
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...
Definition: access_map_pattern_matching.hh:144
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
Prefetcher::AccessMapPatternMatching::AM_PREFETCH
@ AM_PREFETCH
Definition: access_map_pattern_matching.hh:82
name
const std::string & name()
Definition: trace.cc:50
Prefetcher::Base::PrefetchInfo::isSecure
bool isSecure() const
Returns true if the address targets the secure memory space.
Definition: base.hh:126
Prefetcher::AccessMapPatternMatching::accessMapTable
AssociativeSet< AccessMapEntry > accessMapTable
Access map table.
Definition: access_map_pattern_matching.hh:108
Prefetcher::AccessMapPatternMatching::AccessMapEntry::states
std::vector< AccessMapState > states
vector containing the state of the cachelines in this zone
Definition: access_map_pattern_matching.hh:91
Prefetcher::Base::PrefetchInfo
Class containing the information needed by the prefetch to train and generate new prefetch requests.
Definition: base.hh:90
Prefetcher::AccessMapPatternMatching::hotZoneSize
const uint64_t hotZoneSize
Amount of memory covered by a hot zone.
Definition: access_map_pattern_matching.hh:60
ArmISA::stride
Bitfield< 21, 20 > stride
Definition: miscregs_types.hh:441
Prefetcher::AccessMapPatternMatching::setEntryState
void setEntryState(AccessMapEntry &entry, Addr block, enum AccessMapState state)
Updates the state of a block within an AccessMapEntry, also updates the prefetcher metrics.
Definition: access_map_pattern_matching.cc:119
MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:323
Prefetcher::AccessMapPatternMatching::epochEvent
EventFunctionWrapper epochEvent
Definition: access_map_pattern_matching.hh:181
Prefetcher::AccessMapPatternMatching::usefulDegree
unsigned usefulDegree
Current useful degree.
Definition: access_map_pattern_matching.hh:133
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:219
Prefetcher::Base::PrefetchInfo::getAddr
Addr getAddr() const
Obtains the address value of this Prefetcher address.
Definition: base.hh:117
isPowerOf2
bool isPowerOf2(const T &n)
Definition: intmath.hh:102
Prefetcher::AccessMapPatternMatching::lowCacheHitThreshold
const double lowCacheHitThreshold
A cache hit ratio smaller than this is considered low.
Definition: access_map_pattern_matching.hh:72
Prefetcher::AccessMapPatternMatching
Definition: access_map_pattern_matching.hh:51
Prefetcher::AccessMapPatternMatching::blkSize
const unsigned blkSize
Cacheline size used by the prefetcher using this object.
Definition: access_map_pattern_matching.hh:54
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:171

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