gem5 v24.1.0.1
Loading...
Searching...
No Matches
access_map_pattern_matching.cc
Go to the documentation of this file.
1
30
31#include "debug/HWPrefetch.hh"
32#include "params/AMPMPrefetcher.hh"
33#include "params/AccessMapPatternMatching.hh"
34
35namespace gem5
36{
37
38namespace prefetch
39{
40
42 const AccessMapPatternMatchingParams &p)
43 : ClockedObject(p), blkSize(p.block_size), limitStride(p.limit_stride),
44 startDegree(p.start_degree), hotZoneSize(p.hot_zone_size),
45 highCoverageThreshold(p.high_coverage_threshold),
46 lowCoverageThreshold(p.low_coverage_threshold),
47 highAccuracyThreshold(p.high_accuracy_threshold),
48 lowAccuracyThreshold(p.low_accuracy_threshold),
49 highCacheHitThreshold(p.high_cache_hit_threshold),
50 lowCacheHitThreshold(p.low_cache_hit_threshold),
51 epochCycles(p.epoch_cycles),
52 offChipMemoryLatency(p.offchip_memory_latency),
53 accessMapTable("AccessMapTable",
54 p.access_map_table_entries,
55 p.access_map_table_assoc,
56 p.access_map_table_replacement_policy,
57 p.access_map_table_indexing_policy,
58 AccessMapEntry(hotZoneSize / blkSize,
59 genTagExtractor(p.access_map_table_indexing_policy))),
60 numGoodPrefetches(0), numTotalPrefetches(0), numRawCacheMisses(0),
61 numRawCacheHits(0), degree(startDegree), usefulDegree(startDegree),
62 epochEvent([this]{ processEpochEvent(); }, name())
63{
64 fatal_if(!isPowerOf2(hotZoneSize),
65 "the hot zone size must be a power of 2");
66}
67
68void
73
74void
76{
78 double prefetch_accuracy =
79 ((double) numGoodPrefetches) / ((double) numTotalPrefetches);
80 double prefetch_coverage =
81 ((double) numGoodPrefetches) / ((double) numRawCacheMisses);
82 double cache_hit_ratio = ((double) numRawCacheHits) /
84 double num_requests = (double) (numRawCacheMisses - numGoodPrefetches +
86 double memory_bandwidth = num_requests * offChipMemoryLatency /
88
89 if (prefetch_coverage > highCoverageThreshold &&
90 (prefetch_accuracy > highAccuracyThreshold ||
91 cache_hit_ratio < lowCacheHitThreshold)) {
92 usefulDegree += 1;
93 } else if ((prefetch_coverage < lowCoverageThreshold &&
94 (prefetch_accuracy < lowAccuracyThreshold ||
95 cache_hit_ratio > highCacheHitThreshold)) ||
96 (prefetch_accuracy < lowAccuracyThreshold &&
97 cache_hit_ratio > highCacheHitThreshold)) {
98 usefulDegree -= 1;
99 }
100 degree = std::min((unsigned) memory_bandwidth, usefulDegree);
101 // reset epoch stats
102 numGoodPrefetches = 0.0;
103 numTotalPrefetches = 0.0;
104 numRawCacheMisses = 0.0;
105 numRawCacheHits = 0.0;
106}
107
110 bool is_secure)
111{
112 const TaggedEntry::KeyType key{am_addr, is_secure};
113 AccessMapEntry *am_entry = accessMapTable.findEntry(key);
114 if (am_entry != nullptr) {
115 accessMapTable.accessEntry(am_entry);
116 } else {
117 am_entry = accessMapTable.findVictim(key);
118 assert(am_entry != nullptr);
119
120 accessMapTable.insertEntry(key, am_entry);
121 }
122 return am_entry;
123}
124
125void
127 Addr block, enum AccessMapState state)
128{
129 enum AccessMapState old = entry.states[block];
130 entry.states[block] = state;
131
132 //do not update stats when initializing
133 if (state == AM_INIT) return;
134
135 switch (old) {
136 case AM_INIT:
137 if (state == AM_PREFETCH) {
139 } else if (state == AM_ACCESS) {
141 }
142 break;
143 case AM_PREFETCH:
144 if (state == AM_ACCESS) {
147 }
148 break;
149 case AM_ACCESS:
150 if (state == AM_ACCESS) {
151 numRawCacheHits += 1;
152 }
153 break;
154 default:
155 panic("Impossible path\n");
156 break;
157 }
158}
159
160void
163 const CacheAccessor &cache)
164{
165 assert(addresses.empty());
166
167 bool is_secure = pfi.isSecure();
168 Addr am_addr = pfi.getAddr() / hotZoneSize;
169 Addr current_block = (pfi.getAddr() % hotZoneSize) / blkSize;
170 uint64_t lines_per_zone = hotZoneSize / blkSize;
171
172 // Get the entries of the curent block (am_addr), the previous, and the
173 // following ones
174 AccessMapEntry *am_entry_curr = getAccessMapEntry(am_addr, is_secure);
175 AccessMapEntry *am_entry_prev = (am_addr > 0) ?
176 getAccessMapEntry(am_addr-1, is_secure) : nullptr;
177 AccessMapEntry *am_entry_next = (am_addr < (MaxAddr/hotZoneSize)) ?
178 getAccessMapEntry(am_addr+1, is_secure) : nullptr;
179 assert(am_entry_curr != am_entry_prev);
180 assert(am_entry_curr != am_entry_next);
181 assert(am_entry_prev != am_entry_next);
182 assert(am_entry_curr != nullptr);
183
184 //Mark the current access as Accessed
185 setEntryState(*am_entry_curr, current_block, AM_ACCESS);
186
192 std::vector<AccessMapState> states(3 * lines_per_zone);
193 for (unsigned idx = 0; idx < lines_per_zone; idx += 1) {
194 states[idx] =
195 am_entry_prev != nullptr ? am_entry_prev->states[idx] : AM_INVALID;
196 states[idx + lines_per_zone] = am_entry_curr->states[idx];
197 states[idx + 2 * lines_per_zone] =
198 am_entry_next != nullptr ? am_entry_next->states[idx] : AM_INVALID;
199 }
200
207 // index of the current_block in the new vector
208 Addr states_current_block = current_block + lines_per_zone;
209 // consider strides 1..lines_per_zone/2
210 int max_stride = limitStride == 0 ? lines_per_zone / 2 : limitStride + 1;
211 for (int stride = 1; stride < max_stride; stride += 1) {
212 // Test accessed positive strides
213 if (checkCandidate(states, states_current_block, stride)) {
214 // candidate found, current_block - stride
215 Addr pf_addr;
216 if (stride > current_block) {
217 // The index (current_block - stride) falls in the range of
218 // the previous zone (am_entry_prev), adjust the address
219 // accordingly
220 Addr blk = states_current_block - stride;
221 pf_addr = (am_addr - 1) * hotZoneSize + blk * blkSize;
222 setEntryState(*am_entry_prev, blk, AM_PREFETCH);
223 } else {
224 // The index (current_block - stride) falls within
225 // am_entry_curr
226 Addr blk = current_block - stride;
227 pf_addr = am_addr * hotZoneSize + blk * blkSize;
228 setEntryState(*am_entry_curr, blk, AM_PREFETCH);
229 }
230 addresses.push_back(Queued::AddrPriority(pf_addr, 0));
231 if (addresses.size() == degree) {
232 break;
233 }
234 }
235
236 // Test accessed negative strides
237 if (checkCandidate(states, states_current_block, -stride)) {
238 // candidate found, current_block + stride
239 Addr pf_addr;
240 if (current_block + stride >= lines_per_zone) {
241 // The index (current_block + stride) falls in the range of
242 // the next zone (am_entry_next), adjust the address
243 // accordingly
244 Addr blk = (states_current_block + stride) % lines_per_zone;
245 pf_addr = (am_addr + 1) * hotZoneSize + blk * blkSize;
246 setEntryState(*am_entry_next, blk, AM_PREFETCH);
247 } else {
248 // The index (current_block + stride) falls within
249 // am_entry_curr
250 Addr blk = current_block + stride;
251 pf_addr = am_addr * hotZoneSize + blk * blkSize;
252 setEntryState(*am_entry_curr, blk, AM_PREFETCH);
253 }
254 addresses.push_back(Queued::AddrPriority(pf_addr, 0));
255 if (addresses.size() == degree) {
256 break;
257 }
258 }
259 }
260}
261
262AMPM::AMPM(const AMPMPrefetcherParams &p)
263 : Queued(p), ampm(*p.ampm)
264{
265}
266
267void
269 std::vector<AddrPriority> &addresses,
270 const CacheAccessor &cache)
271{
272 ampm.calculatePrefetch(pfi, addresses, cache);
273}
274
275} // namespace prefetch
276} // namespace gem5
The ClockedObject class extends the SimObject with a clock and accessor functions to relate ticks to ...
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...
Tick cyclesToTicks(Cycles c) const
AMPM(const AMPMPrefetcherParams &p)
void calculatePrefetch(const PrefetchInfo &pfi, std::vector< AddrPriority > &addresses, const CacheAccessor &cache) override
AccessMapPatternMatching & ampm
AccessMapState
Data type representing the state of a cacheline in the access map.
uint64_t numGoodPrefetches
Number of good prefetches.
AccessMapPatternMatching(const AccessMapPatternMatchingParams &p)
uint64_t numTotalPrefetches
Number of prefetches issued.
const double highCoverageThreshold
A prefetch coverage factor bigger than this is considered high.
uint64_t numRawCacheMisses
Number of raw cache misses.
const Tick offChipMemoryLatency
Off chip memory latency to use for the epoch bandwidth calculation.
const unsigned limitStride
Limit the stride checking to -limitStride/+limitStride.
void startup() override
startup() is the final initialization call before simulation.
const double highCacheHitThreshold
A cache hit ratio bigger than this is considered high.
void processEpochEvent()
This event constitues the epoch of the statistics that keep track of the prefetcher accuracy,...
const double lowAccuracyThreshold
A prefetch accuracy factor smaller than this is considered low.
const double lowCacheHitThreshold
A cache hit ratio smaller than this is considered low.
const double highAccuracyThreshold
A prefetch accuracy factor bigger than this is considered high.
void calculatePrefetch(const Base::PrefetchInfo &pfi, std::vector< Queued::AddrPriority > &addresses, const CacheAccessor &cache)
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...
const unsigned blkSize
Cacheline size used by the prefetcher using this object.
const double lowCoverageThreshold
A prefetch coverage factor smaller than this is considered low.
const Cycles epochCycles
Cycles in an epoch period.
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 ...
const uint64_t hotZoneSize
Amount of memory covered by a hot zone.
AssociativeCache< AccessMapEntry > accessMapTable
Access map table.
Class containing the information needed by the prefetch to train and generate new prefetch requests.
Definition base.hh:111
bool isSecure() const
Returns true if the address targets the secure memory space.
Definition base.hh:147
Addr getAddr() const
Obtains the address value of this Prefetcher address.
Definition base.hh:138
STL pair class.
Definition stl.hh:58
STL vector class.
Definition stl.hh:37
static constexpr bool isPowerOf2(const T &n)
Definition intmath.hh:98
void schedule(Event &event, Tick when)
Definition eventq.hh:1012
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:188
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition logging.hh:236
atomic_var_t state
Definition helpers.cc:211
Bitfield< 21, 20 > stride
Bitfield< 0 > p
Copyright (c) 2024 Arm Limited All rights reserved.
Definition binary32.hh:36
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition types.hh:147
static constexpr auto genTagExtractor(BTBIndexingPolicy *ip)
This helper generates a tag extractor function object which will be typically used by Replaceable ent...
Definition btb_entry.hh:281
const Addr MaxAddr
Definition types.hh:171
Provides generic cache lookup functions.
std::vector< AccessMapState > states
vector containing the state of the cachelines in this zone
const std::string & name()
Definition trace.cc:48

Generated on Mon Jan 13 2025 04:28:38 for gem5 by doxygen 1.9.8