gem5 [DEVELOP-FOR-25.0]
Loading...
Searching...
No Matches
access_map_pattern_matching.cc
Go to the documentation of this file.
1
28
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,
59 genTagExtractor(p.access_map_table_indexing_policy))),
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
206
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
ClockedObject(const ClockedObjectParams &p)
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
TaggedTypes::KeyType KeyType
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 startDegree
Maximum number of prefetch generated.
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:113
bool isSecure() const
Returns true if the address targets the secure memory space.
Definition base.hh:149
Addr getAddr() const
Obtains the address value of this Prefetcher address.
Definition base.hh:140
Queued(const QueuedPrefetcherParams &p)
Definition queued.cc:100
std::pair< Addr, int32_t > AddrPriority
Definition queued.hh:192
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:220
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition logging.hh:268
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 May 26 2025 09:19:11 for gem5 by doxygen 1.13.2