gem5 v24.1.0.1
Loading...
Searching...
No Matches
indirect_memory.cc
Go to the documentation of this file.
1
30
31 #include "mem/cache/base.hh"
32 #include "params/IndirectMemoryPrefetcher.hh"
33
34namespace gem5
35{
36
37namespace prefetch
38{
39
40IndirectMemory::IndirectMemory(const IndirectMemoryPrefetcherParams &p)
41 : Queued(p),
42 maxPrefetchDistance(p.max_prefetch_distance),
43 shiftValues(p.shift_values), prefetchThreshold(p.prefetch_threshold),
44 streamCounterThreshold(p.stream_counter_threshold),
45 streamingDistance(p.streaming_distance),
46 prefetchTable((name() + ".PrefetchTable").c_str(),
47 p.pt_table_entries,
48 p.pt_table_assoc,
49 p.pt_table_replacement_policy,
50 p.pt_table_indexing_policy,
51 PrefetchTableEntry(p.num_indirect_counter_bits,
52 genTagExtractor(p.pt_table_indexing_policy))),
53 ipd((name() + ".IPD").c_str(), p.ipd_table_entries, p.ipd_table_assoc,
54 p.ipd_table_replacement_policy,
55 p.ipd_table_indexing_policy,
56 IndirectPatternDetectorEntry(p.addr_array_len, shiftValues.size(),
57 genTagExtractor(p.ipd_table_indexing_policy))),
58 ipdEntryTrackingMisses(nullptr), byteOrder(p.sys->getGuestByteOrder())
59{
60}
61
62void
65 const CacheAccessor &cache)
66{
67 // This prefetcher requires a PC
68 if (!pfi.hasPC()) {
69 return;
70 }
71
72 bool is_secure = pfi.isSecure();
73 Addr pc = pfi.getPC();
74 Addr addr = pfi.getAddr();
75 bool miss = pfi.isCacheMiss();
76
78
79 // First check if this is a miss, if the prefetcher is tracking misses
80 if (ipdEntryTrackingMisses != nullptr && miss) {
81 // Check if the entry tracking misses has already set its second index
84 } else {
86 }
87 } else {
88 // if misses are not being tracked, attempt to detect stream accesses
89 const PrefetchTableEntry::KeyType key{pc, is_secure};
90 PrefetchTableEntry *pt_entry = prefetchTable.findEntry(key);
91 if (pt_entry != nullptr) {
92 prefetchTable.accessEntry(pt_entry);
93
94 if (pt_entry->address != addr) {
95 // Streaming access found
96 pt_entry->streamCounter += 1;
97 if (pt_entry->streamCounter >= streamCounterThreshold) {
98 int64_t delta = addr - pt_entry->address;
99 for (unsigned int i = 1; i <= streamingDistance; i += 1) {
100 addresses.push_back(AddrPriority(addr + delta * i, 0));
101 }
102 }
103 pt_entry->address = addr;
104 pt_entry->secure = is_secure;
105
106
107 // if this is a read, read the data from the cache and assume
108 // it is an index (this is only possible if the data is already
109 // in the cache), also, only indexes up to 8 bytes are
110 // considered
111
112 if (!miss && !pfi.isWrite() && pfi.getSize() <= 8) {
113 int64_t index = 0;
114 bool read_index = true;
115 switch(pfi.getSize()) {
116 case sizeof(uint8_t):
117 index = pfi.get<uint8_t>(byteOrder);
118 break;
119 case sizeof(uint16_t):
120 index = pfi.get<uint16_t>(byteOrder);
121 break;
122 case sizeof(uint32_t):
123 index = pfi.get<uint32_t>(byteOrder);
124 break;
125 case sizeof(uint64_t):
126 index = pfi.get<uint64_t>(byteOrder);
127 break;
128 default:
129 // Ignore non-power-of-two sizes
130 read_index = false;
131 }
132 if (read_index && !pt_entry->enabled) {
133 // Not enabled (no pattern detected in this stream),
134 // add or update an entry in the pattern detector and
135 // start tracking misses
137 } else if (read_index) {
138 // Enabled entry, update the index
139 pt_entry->index = index;
140 if (!pt_entry->increasedIndirectCounter) {
141 pt_entry->indirectCounter--;
142 } else {
143 // Set this to false, to see if the new index
144 // has any match
145 pt_entry->increasedIndirectCounter = false;
146 }
147
148 // If the counter is high enough, start prefetching
149 if (pt_entry->indirectCounter > prefetchThreshold) {
150 unsigned distance = maxPrefetchDistance *
152 for (int delta = 1; delta < distance; delta += 1) {
153 Addr pf_addr = pt_entry->baseAddr +
154 (pt_entry->index << pt_entry->shift);
155 addresses.push_back(AddrPriority(pf_addr, 0));
156 }
157 }
158 }
159 }
160 }
161 } else {
162 pt_entry = prefetchTable.findVictim(key);
163 assert(pt_entry != nullptr);
164 prefetchTable.insertEntry(key, pt_entry);
165 pt_entry->address = addr;
166 pt_entry->secure = is_secure;
167 }
168 }
169}
170
171void
173 const PrefetchTableEntry *pt_entry, int64_t index)
174{
175 // The address of the pt_entry is used to index the IPD
176 Addr ipd_entry_addr = (Addr) pt_entry;
177 const IndirectPatternDetectorEntry::KeyType key{ipd_entry_addr, false};
178 IndirectPatternDetectorEntry *ipd_entry = ipd.findEntry(key);
179 if (ipd_entry != nullptr) {
180 ipd.accessEntry(ipd_entry);
181 if (!ipd_entry->secondIndexSet) {
182 // Second time we see an index, fill idx2
183 ipd_entry->idx2 = index;
184 ipd_entry->secondIndexSet = true;
185 ipdEntryTrackingMisses = ipd_entry;
186 } else {
187 // Third access! no pattern has been found so far,
188 // release the IPD entry
189 ipd.invalidate(ipd_entry);
190 ipdEntryTrackingMisses = nullptr;
191 }
192 } else {
193 ipd_entry = ipd.findVictim(key);
194 assert(ipd_entry != nullptr);
195 ipd.insertEntry(key, ipd_entry);
196 ipd_entry->idx1 = index;
197 ipdEntryTrackingMisses = ipd_entry;
198 }
199}
200
201void
203{
205 // If the second index is not set, we are just filling the baseAddr
206 // vector
207 assert(entry->numMisses < entry->baseAddr.size());
208 std::vector<Addr> &ba_array = entry->baseAddr[entry->numMisses];
209 int idx = 0;
210 for (int shift : shiftValues) {
211 ba_array[idx] = miss_addr - (entry->idx1 << shift);
212 idx += 1;
213 }
214 entry->numMisses += 1;
215 if (entry->numMisses == entry->baseAddr.size()) {
216 // stop tracking misses once we have tracked enough
217 ipdEntryTrackingMisses = nullptr;
218 }
219}
220void
222{
224 // Second index is filled, compare the addresses generated during
225 // the previous misses (using idx1) against newly generated values
226 // using idx2, if a match is found, fill the additional fields
227 // of the PT entry
228 for (int midx = 0; midx < entry->numMisses; midx += 1)
229 {
230 std::vector<Addr> &ba_array = entry->baseAddr[midx];
231 int idx = 0;
232 for (int shift : shiftValues) {
233 if (ba_array[idx] == (miss_addr - (entry->idx2 << shift))) {
234 // Match found!
235 // Fill the corresponding pt_entry
236 PrefetchTableEntry *pt_entry =
237 (PrefetchTableEntry *) entry->getTag();
238 pt_entry->baseAddr = ba_array[idx];
239 pt_entry->shift = shift;
240 pt_entry->enabled = true;
241 pt_entry->indirectCounter.reset();
242 // Release the current IPD Entry
243 ipd.invalidate(entry);
244 // Do not track more misses
245 ipdEntryTrackingMisses = nullptr;
246 return;
247 }
248 idx += 1;
249 }
250 }
251}
252
253void
255{
256 for (auto &pt_entry : prefetchTable) {
257 if (pt_entry.enabled) {
258 if (addr == pt_entry.baseAddr +
259 (pt_entry.index << pt_entry.shift)) {
260 pt_entry.indirectCounter++;
261 pt_entry.increasedIndirectCounter = true;
262 }
263 }
264 }
265}
266
267} // namespace prefetch
268} // namespace gem5
virtual Addr getTag() const
Get tag associated to this block.
Class containing the information needed by the prefetch to train and generate new prefetch requests.
Definition base.hh:111
Addr getPC() const
Returns the program counter that generated this request.
Definition base.hh:156
bool isSecure() const
Returns true if the address targets the secure memory space.
Definition base.hh:147
unsigned int getSize() const
Gets the size of the request triggering this event.
Definition base.hh:184
bool isWrite() const
Checks if the request that caused this prefetch event was a write request.
Definition base.hh:194
bool isCacheMiss() const
Check if this event comes from a cache miss.
Definition base.hh:212
Addr getAddr() const
Obtains the address value of this Prefetcher address.
Definition base.hh:138
T get(ByteOrder endian) const
Gets the associated data of the request triggering the event.
Definition base.hh:224
bool hasPC() const
Returns true if the associated program counter is valid.
Definition base.hh:166
const int streamCounterThreshold
streamCounter value to trigger the streaming prefetcher
void trackMissIndex1(Addr miss_addr)
Update an IPD entry with a detected miss address, when the first index is being tracked.
AssociativeCache< IndirectPatternDetectorEntry > ipd
Indirect Pattern Detector (IPD) table.
void trackMissIndex2(Addr miss_addr)
Update an IPD entry with a detected miss address, when the second index is being tracked.
const ByteOrder byteOrder
Byte order used to access the cache.
void checkAccessMatchOnActiveEntries(Addr addr)
Checks if an access to the cache matches any active PT entry, if so, the indirect confidence counter ...
const unsigned int maxPrefetchDistance
Maximum number of prefetches generated per event.
const std::vector< int > shiftValues
Shift values considered.
IndirectPatternDetectorEntry * ipdEntryTrackingMisses
Entry currently tracking misses.
const int streamingDistance
Number of prefetches generated when using the streaming prefetcher.
AssociativeCache< PrefetchTableEntry > prefetchTable
Prefetch table.
const unsigned int prefetchThreshold
Counter threshold to start prefetching.
IndirectMemory(const IndirectMemoryPrefetcherParams &p)
void calculatePrefetch(const PrefetchInfo &pfi, std::vector< AddrPriority > &addresses, const CacheAccessor &cache) override
void allocateOrUpdateIPDEntry(const PrefetchTableEntry *pt_entry, int64_t index)
Allocate or update an entry in the IPD.
std::pair< Addr, int32_t > AddrPriority
Definition queued.hh:192
STL vector class.
Definition stl.hh:37
double calcSaturation() const
Calculate saturation percentile of the current counter's value with regard to its maximum possible va...
void reset()
Reset the counter to its initial value.
Declares a basic cache interface BaseCache.
ByteOrder byteOrder(const ThreadContext *tc)
Definition utility.hh:359
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 6, 5 > shift
Definition types.hh:117
Bitfield< 4 > pc
Bitfield< 30, 0 > index
Bitfield< 0 > p
Bitfield< 3 > addr
Definition types.hh:84
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
Provides generic cache lookup functions.
std::vector< std::vector< Addr > > baseAddr
Potential BaseAddr candidates for each recorded miss.
bool increasedIndirectCounter
This variable is set to indicate that there has been at least one match with the current index value.
bool enabled
Enable bit of the indirect fields.
bool secure
Whether this address is in the secure region.
SatCounter8 indirectCounter
Confidence counter of the indirect fields.
unsigned int streamCounter
Confidence counter of the stream.
const std::string & name()
Definition trace.cc:48

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