gem5 v24.0.0.0
Loading...
Searching...
No Matches
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
36namespace gem5
37{
38
39namespace prefetch
40{
41
43 const AccessMapPatternMatchingParams &p)
44 : ClockedObject(p), blkSize(p.block_size), limitStride(p.limit_stride),
45 startDegree(p.start_degree), hotZoneSize(p.hot_zone_size),
46 highCoverageThreshold(p.high_coverage_threshold),
47 lowCoverageThreshold(p.low_coverage_threshold),
48 highAccuracyThreshold(p.high_accuracy_threshold),
49 lowAccuracyThreshold(p.low_accuracy_threshold),
50 highCacheHitThreshold(p.high_cache_hit_threshold),
51 lowCacheHitThreshold(p.low_cache_hit_threshold),
52 epochCycles(p.epoch_cycles),
53 offChipMemoryLatency(p.offchip_memory_latency),
54 accessMapTable("AccessMapTable",
55 p.access_map_table_entries,
56 p.access_map_table_assoc,
57 p.access_map_table_replacement_policy,
58 p.access_map_table_indexing_policy,
59 AccessMapEntry(hotZoneSize / blkSize)),
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 AccessMapEntry *am_entry = accessMapTable.findEntry(am_addr, is_secure);
113 if (am_entry != nullptr) {
114 accessMapTable.accessEntry(am_entry);
115 } else {
116 am_entry = accessMapTable.findVictim(am_addr);
117 assert(am_entry != nullptr);
118
119 accessMapTable.insertEntry(am_addr, is_secure, am_entry);
120 }
121 return am_entry;
122}
123
124void
126 Addr block, enum AccessMapState state)
127{
128 enum AccessMapState old = entry.states[block];
129 entry.states[block] = state;
130
131 //do not update stats when initializing
132 if (state == AM_INIT) return;
133
134 switch (old) {
135 case AM_INIT:
136 if (state == AM_PREFETCH) {
138 } else if (state == AM_ACCESS) {
140 }
141 break;
142 case AM_PREFETCH:
143 if (state == AM_ACCESS) {
146 }
147 break;
148 case AM_ACCESS:
149 if (state == AM_ACCESS) {
150 numRawCacheHits += 1;
151 }
152 break;
153 default:
154 panic("Impossible path\n");
155 break;
156 }
157}
158
159void
162 const CacheAccessor &cache)
163{
164 assert(addresses.empty());
165
166 bool is_secure = pfi.isSecure();
167 Addr am_addr = pfi.getAddr() / hotZoneSize;
168 Addr current_block = (pfi.getAddr() % hotZoneSize) / blkSize;
169 uint64_t lines_per_zone = hotZoneSize / blkSize;
170
171 // Get the entries of the curent block (am_addr), the previous, and the
172 // following ones
173 AccessMapEntry *am_entry_curr = getAccessMapEntry(am_addr, is_secure);
174 AccessMapEntry *am_entry_prev = (am_addr > 0) ?
175 getAccessMapEntry(am_addr-1, is_secure) : nullptr;
176 AccessMapEntry *am_entry_next = (am_addr < (MaxAddr/hotZoneSize)) ?
177 getAccessMapEntry(am_addr+1, is_secure) : nullptr;
178 assert(am_entry_curr != am_entry_prev);
179 assert(am_entry_curr != am_entry_next);
180 assert(am_entry_prev != am_entry_next);
181 assert(am_entry_curr != nullptr);
182
183 //Mark the current access as Accessed
184 setEntryState(*am_entry_curr, current_block, AM_ACCESS);
185
191 std::vector<AccessMapState> states(3 * lines_per_zone);
192 for (unsigned idx = 0; idx < lines_per_zone; idx += 1) {
193 states[idx] =
194 am_entry_prev != nullptr ? am_entry_prev->states[idx] : AM_INVALID;
195 states[idx + lines_per_zone] = am_entry_curr->states[idx];
196 states[idx + 2 * lines_per_zone] =
197 am_entry_next != nullptr ? am_entry_next->states[idx] : AM_INVALID;
198 }
199
206 // index of the current_block in the new vector
207 Addr states_current_block = current_block + lines_per_zone;
208 // consider strides 1..lines_per_zone/2
209 int max_stride = limitStride == 0 ? lines_per_zone / 2 : limitStride + 1;
210 for (int stride = 1; stride < max_stride; stride += 1) {
211 // Test accessed positive strides
212 if (checkCandidate(states, states_current_block, stride)) {
213 // candidate found, current_block - stride
214 Addr pf_addr;
215 if (stride > current_block) {
216 // The index (current_block - stride) falls in the range of
217 // the previous zone (am_entry_prev), adjust the address
218 // accordingly
219 Addr blk = states_current_block - stride;
220 pf_addr = (am_addr - 1) * hotZoneSize + blk * blkSize;
221 setEntryState(*am_entry_prev, blk, AM_PREFETCH);
222 } else {
223 // The index (current_block - stride) falls within
224 // am_entry_curr
225 Addr blk = current_block - stride;
226 pf_addr = am_addr * hotZoneSize + blk * blkSize;
227 setEntryState(*am_entry_curr, blk, AM_PREFETCH);
228 }
229 addresses.push_back(Queued::AddrPriority(pf_addr, 0));
230 if (addresses.size() == degree) {
231 break;
232 }
233 }
234
235 // Test accessed negative strides
236 if (checkCandidate(states, states_current_block, -stride)) {
237 // candidate found, current_block + stride
238 Addr pf_addr;
239 if (current_block + stride >= lines_per_zone) {
240 // The index (current_block + stride) falls in the range of
241 // the next zone (am_entry_next), adjust the address
242 // accordingly
243 Addr blk = (states_current_block + stride) % lines_per_zone;
244 pf_addr = (am_addr + 1) * hotZoneSize + blk * blkSize;
245 setEntryState(*am_entry_next, blk, AM_PREFETCH);
246 } else {
247 // The index (current_block + stride) falls within
248 // am_entry_curr
249 Addr blk = current_block + stride;
250 pf_addr = am_addr * hotZoneSize + blk * blkSize;
251 setEntryState(*am_entry_curr, blk, AM_PREFETCH);
252 }
253 addresses.push_back(Queued::AddrPriority(pf_addr, 0));
254 if (addresses.size() == degree) {
255 break;
256 }
257 }
258 }
259}
260
261AMPM::AMPM(const AMPMPrefetcherParams &p)
262 : Queued(p), ampm(*p.ampm)
263{
264}
265
266void
268 std::vector<AddrPriority> &addresses,
269 const CacheAccessor &cache)
270{
271 ampm.calculatePrefetch(pfi, addresses, cache);
272}
273
274} // namespace prefetch
275} // 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.
AssociativeSet< AccessMapEntry > accessMapTable
Access map table.
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.
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 - Pranith Kumar Copyright (c) 2020 Inria 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
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 Tue Jun 18 2024 16:24:05 for gem5 by doxygen 1.11.0