gem5 v23.0.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"
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(p.access_map_table_assoc, p.access_map_table_entries,
55 p.access_map_table_indexing_policy,
56 p.access_map_table_replacement_policy,
57 AccessMapEntry(hotZoneSize / blkSize)),
58 numGoodPrefetches(0), numTotalPrefetches(0), numRawCacheMisses(0),
59 numRawCacheHits(0), degree(startDegree), usefulDegree(startDegree),
60 epochEvent([this]{ processEpochEvent(); }, name())
61{
62 fatal_if(!isPowerOf2(hotZoneSize),
63 "the hot zone size must be a power of 2");
64}
65
66void
68{
70}
71
72void
74{
76 double prefetch_accuracy =
77 ((double) numGoodPrefetches) / ((double) numTotalPrefetches);
78 double prefetch_coverage =
79 ((double) numGoodPrefetches) / ((double) numRawCacheMisses);
80 double cache_hit_ratio = ((double) numRawCacheHits) /
82 double num_requests = (double) (numRawCacheMisses - numGoodPrefetches +
84 double memory_bandwidth = num_requests * offChipMemoryLatency /
86
87 if (prefetch_coverage > highCoverageThreshold &&
88 (prefetch_accuracy > highAccuracyThreshold ||
89 cache_hit_ratio < lowCacheHitThreshold)) {
90 usefulDegree += 1;
91 } else if ((prefetch_coverage < lowCoverageThreshold &&
92 (prefetch_accuracy < lowAccuracyThreshold ||
93 cache_hit_ratio > highCacheHitThreshold)) ||
94 (prefetch_accuracy < lowAccuracyThreshold &&
95 cache_hit_ratio > highCacheHitThreshold)) {
96 usefulDegree -= 1;
97 }
98 degree = std::min((unsigned) memory_bandwidth, usefulDegree);
99 // reset epoch stats
100 numGoodPrefetches = 0.0;
101 numTotalPrefetches = 0.0;
102 numRawCacheMisses = 0.0;
103 numRawCacheHits = 0.0;
104}
105
108 bool is_secure)
109{
110 AccessMapEntry *am_entry = accessMapTable.findEntry(am_addr, is_secure);
111 if (am_entry != nullptr) {
112 accessMapTable.accessEntry(am_entry);
113 } else {
114 am_entry = accessMapTable.findVictim(am_addr);
115 assert(am_entry != nullptr);
116
117 accessMapTable.insertEntry(am_addr, is_secure, am_entry);
118 }
119 return am_entry;
120}
121
122void
124 Addr block, enum AccessMapState state)
125{
126 enum AccessMapState old = entry.states[block];
127 entry.states[block] = state;
128
129 //do not update stats when initializing
130 if (state == AM_INIT) return;
131
132 switch (old) {
133 case AM_INIT:
134 if (state == AM_PREFETCH) {
136 } else if (state == AM_ACCESS) {
138 }
139 break;
140 case AM_PREFETCH:
141 if (state == AM_ACCESS) {
144 }
145 break;
146 case AM_ACCESS:
147 if (state == AM_ACCESS) {
148 numRawCacheHits += 1;
149 }
150 break;
151 default:
152 panic("Impossible path\n");
153 break;
154 }
155}
156
157void
160{
161 assert(addresses.empty());
162
163 bool is_secure = pfi.isSecure();
164 Addr am_addr = pfi.getAddr() / hotZoneSize;
165 Addr current_block = (pfi.getAddr() % hotZoneSize) / blkSize;
166 uint64_t lines_per_zone = hotZoneSize / blkSize;
167
168 // Get the entries of the curent block (am_addr), the previous, and the
169 // following ones
170 AccessMapEntry *am_entry_curr = getAccessMapEntry(am_addr, is_secure);
171 AccessMapEntry *am_entry_prev = (am_addr > 0) ?
172 getAccessMapEntry(am_addr-1, is_secure) : nullptr;
173 AccessMapEntry *am_entry_next = (am_addr < (MaxAddr/hotZoneSize)) ?
174 getAccessMapEntry(am_addr+1, is_secure) : nullptr;
175 assert(am_entry_curr != am_entry_prev);
176 assert(am_entry_curr != am_entry_next);
177 assert(am_entry_prev != am_entry_next);
178 assert(am_entry_curr != nullptr);
179
180 //Mark the current access as Accessed
181 setEntryState(*am_entry_curr, current_block, AM_ACCESS);
182
188 std::vector<AccessMapState> states(3 * lines_per_zone);
189 for (unsigned idx = 0; idx < lines_per_zone; idx += 1) {
190 states[idx] =
191 am_entry_prev != nullptr ? am_entry_prev->states[idx] : AM_INVALID;
192 states[idx + lines_per_zone] = am_entry_curr->states[idx];
193 states[idx + 2 * lines_per_zone] =
194 am_entry_next != nullptr ? am_entry_next->states[idx] : AM_INVALID;
195 }
196
203 // index of the current_block in the new vector
204 Addr states_current_block = current_block + lines_per_zone;
205 // consider strides 1..lines_per_zone/2
206 int max_stride = limitStride == 0 ? lines_per_zone / 2 : limitStride + 1;
207 for (int stride = 1; stride < max_stride; stride += 1) {
208 // Test accessed positive strides
209 if (checkCandidate(states, states_current_block, stride)) {
210 // candidate found, current_block - stride
211 Addr pf_addr;
212 if (stride > current_block) {
213 // The index (current_block - stride) falls in the range of
214 // the previous zone (am_entry_prev), adjust the address
215 // accordingly
216 Addr blk = states_current_block - stride;
217 pf_addr = (am_addr - 1) * hotZoneSize + blk * blkSize;
218 setEntryState(*am_entry_prev, blk, AM_PREFETCH);
219 } else {
220 // The index (current_block - stride) falls within
221 // am_entry_curr
222 Addr blk = current_block - stride;
223 pf_addr = am_addr * hotZoneSize + blk * blkSize;
224 setEntryState(*am_entry_curr, blk, AM_PREFETCH);
225 }
226 addresses.push_back(Queued::AddrPriority(pf_addr, 0));
227 if (addresses.size() == degree) {
228 break;
229 }
230 }
231
232 // Test accessed negative strides
233 if (checkCandidate(states, states_current_block, -stride)) {
234 // candidate found, current_block + stride
235 Addr pf_addr;
236 if (current_block + stride >= lines_per_zone) {
237 // The index (current_block + stride) falls in the range of
238 // the next zone (am_entry_next), adjust the address
239 // accordingly
240 Addr blk = (states_current_block + stride) % lines_per_zone;
241 pf_addr = (am_addr + 1) * hotZoneSize + blk * blkSize;
242 setEntryState(*am_entry_next, blk, AM_PREFETCH);
243 } else {
244 // The index (current_block + stride) falls within
245 // am_entry_curr
246 Addr blk = current_block + stride;
247 pf_addr = am_addr * hotZoneSize + blk * blkSize;
248 setEntryState(*am_entry_curr, blk, AM_PREFETCH);
249 }
250 addresses.push_back(Queued::AddrPriority(pf_addr, 0));
251 if (addresses.size() == degree) {
252 break;
253 }
254 }
255 }
256}
257
258AMPM::AMPM(const AMPMPrefetcherParams &p)
259 : Queued(p), ampm(*p.ampm)
260{
261}
262
263void
265 std::vector<AddrPriority> &addresses)
266{
267 ampm.calculatePrefetch(pfi, addresses);
268}
269
270} // namespace prefetch
271} // 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) 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 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.
void calculatePrefetch(const Base::PrefetchInfo &pfi, std::vector< Queued::AddrPriority > &addresses)
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:97
bool isSecure() const
Returns true if the address targets the secure memory space.
Definition base.hh:133
Addr getAddr() const
Obtains the address value of this Prefetcher address.
Definition base.hh:124
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:188
Bitfield< 21, 20 > stride
Bitfield< 0 > p
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
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
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 Jul 10 2023 15:32:04 for gem5 by doxygen 1.9.7