gem5 v24.0.0.0
Loading...
Searching...
No Matches
indirect_memory.cc
Go to the documentation of this file.
1
30
31 #include "mem/cache/base.hh"
33 #include "params/IndirectMemoryPrefetcher.hh"
34
35namespace gem5
36{
37
38namespace prefetch
39{
40
41IndirectMemory::IndirectMemory(const IndirectMemoryPrefetcherParams &p)
42 : Queued(p),
43 maxPrefetchDistance(p.max_prefetch_distance),
44 shiftValues(p.shift_values), prefetchThreshold(p.prefetch_threshold),
45 streamCounterThreshold(p.stream_counter_threshold),
46 streamingDistance(p.streaming_distance),
47 prefetchTable((name() + ".PrefetchTable").c_str(),
48 p.pt_table_entries,
49 p.pt_table_assoc,
50 p.pt_table_replacement_policy,
51 p.pt_table_indexing_policy,
52 PrefetchTableEntry(p.num_indirect_counter_bits)),
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 ipdEntryTrackingMisses(nullptr), byteOrder(p.sys->getGuestByteOrder())
58{
59}
60
61void
64 const CacheAccessor &cache)
65{
66 // This prefetcher requires a PC
67 if (!pfi.hasPC()) {
68 return;
69 }
70
71 bool is_secure = pfi.isSecure();
72 Addr pc = pfi.getPC();
73 Addr addr = pfi.getAddr();
74 bool miss = pfi.isCacheMiss();
75
77
78 // First check if this is a miss, if the prefetcher is tracking misses
79 if (ipdEntryTrackingMisses != nullptr && miss) {
80 // Check if the entry tracking misses has already set its second index
83 } else {
85 }
86 } else {
87 // if misses are not being tracked, attempt to detect stream accesses
88 PrefetchTableEntry *pt_entry = prefetchTable.findEntry(pc);
89 if (pt_entry != nullptr) {
90 prefetchTable.accessEntry(pt_entry);
91
92 if (pt_entry->address != addr) {
93 // Streaming access found
94 pt_entry->streamCounter += 1;
95 if (pt_entry->streamCounter >= streamCounterThreshold) {
96 int64_t delta = addr - pt_entry->address;
97 for (unsigned int i = 1; i <= streamingDistance; i += 1) {
98 addresses.push_back(AddrPriority(addr + delta * i, 0));
99 }
100 }
101 pt_entry->address = addr;
102 pt_entry->secure = is_secure;
103
104
105 // if this is a read, read the data from the cache and assume
106 // it is an index (this is only possible if the data is already
107 // in the cache), also, only indexes up to 8 bytes are
108 // considered
109
110 if (!miss && !pfi.isWrite() && pfi.getSize() <= 8) {
111 int64_t index = 0;
112 bool read_index = true;
113 switch(pfi.getSize()) {
114 case sizeof(uint8_t):
115 index = pfi.get<uint8_t>(byteOrder);
116 break;
117 case sizeof(uint16_t):
118 index = pfi.get<uint16_t>(byteOrder);
119 break;
120 case sizeof(uint32_t):
121 index = pfi.get<uint32_t>(byteOrder);
122 break;
123 case sizeof(uint64_t):
124 index = pfi.get<uint64_t>(byteOrder);
125 break;
126 default:
127 // Ignore non-power-of-two sizes
128 read_index = false;
129 }
130 if (read_index && !pt_entry->enabled) {
131 // Not enabled (no pattern detected in this stream),
132 // add or update an entry in the pattern detector and
133 // start tracking misses
135 } else if (read_index) {
136 // Enabled entry, update the index
137 pt_entry->index = index;
138 if (!pt_entry->increasedIndirectCounter) {
139 pt_entry->indirectCounter--;
140 } else {
141 // Set this to false, to see if the new index
142 // has any match
143 pt_entry->increasedIndirectCounter = false;
144 }
145
146 // If the counter is high enough, start prefetching
147 if (pt_entry->indirectCounter > prefetchThreshold) {
148 unsigned distance = maxPrefetchDistance *
150 for (int delta = 1; delta < distance; delta += 1) {
151 Addr pf_addr = pt_entry->baseAddr +
152 (pt_entry->index << pt_entry->shift);
153 addresses.push_back(AddrPriority(pf_addr, 0));
154 }
155 }
156 }
157 }
158 }
159 } else {
160 pt_entry = prefetchTable.findVictim(pc);
161 assert(pt_entry != nullptr);
162 prefetchTable.insertEntry(pc, pt_entry);
163 pt_entry->address = addr;
164 pt_entry->secure = is_secure;
165 }
166 }
167}
168
169void
171 const PrefetchTableEntry *pt_entry, int64_t index)
172{
173 // The address of the pt_entry is used to index the IPD
174 Addr ipd_entry_addr = (Addr) pt_entry;
175 IndirectPatternDetectorEntry *ipd_entry = ipd.findEntry(ipd_entry_addr);
176 if (ipd_entry != nullptr) {
177 ipd.accessEntry(ipd_entry);
178 if (!ipd_entry->secondIndexSet) {
179 // Second time we see an index, fill idx2
180 ipd_entry->idx2 = index;
181 ipd_entry->secondIndexSet = true;
182 ipdEntryTrackingMisses = ipd_entry;
183 } else {
184 // Third access! no pattern has been found so far,
185 // release the IPD entry
186 ipd.invalidate(ipd_entry);
187 ipdEntryTrackingMisses = nullptr;
188 }
189 } else {
190 ipd_entry = ipd.findVictim(ipd_entry_addr);
191 assert(ipd_entry != nullptr);
192 ipd.insertEntry(ipd_entry_addr, ipd_entry);
193 ipd_entry->idx1 = index;
194 ipdEntryTrackingMisses = ipd_entry;
195 }
196}
197
198void
200{
202 // If the second index is not set, we are just filling the baseAddr
203 // vector
204 assert(entry->numMisses < entry->baseAddr.size());
205 std::vector<Addr> &ba_array = entry->baseAddr[entry->numMisses];
206 int idx = 0;
207 for (int shift : shiftValues) {
208 ba_array[idx] = miss_addr - (entry->idx1 << shift);
209 idx += 1;
210 }
211 entry->numMisses += 1;
212 if (entry->numMisses == entry->baseAddr.size()) {
213 // stop tracking misses once we have tracked enough
214 ipdEntryTrackingMisses = nullptr;
215 }
216}
217void
219{
221 // Second index is filled, compare the addresses generated during
222 // the previous misses (using idx1) against newly generated values
223 // using idx2, if a match is found, fill the additional fields
224 // of the PT entry
225 for (int midx = 0; midx < entry->numMisses; midx += 1)
226 {
227 std::vector<Addr> &ba_array = entry->baseAddr[midx];
228 int idx = 0;
229 for (int shift : shiftValues) {
230 if (ba_array[idx] == (miss_addr - (entry->idx2 << shift))) {
231 // Match found!
232 // Fill the corresponding pt_entry
233 PrefetchTableEntry *pt_entry =
234 (PrefetchTableEntry *) entry->getTag();
235 pt_entry->baseAddr = ba_array[idx];
236 pt_entry->shift = shift;
237 pt_entry->enabled = true;
238 pt_entry->indirectCounter.reset();
239 // Release the current IPD Entry
240 ipd.invalidate(entry);
241 // Do not track more misses
242 ipdEntryTrackingMisses = nullptr;
243 return;
244 }
245 idx += 1;
246 }
247 }
248}
249
250void
252{
253 for (auto &pt_entry : prefetchTable) {
254 if (pt_entry.enabled) {
255 if (addr == pt_entry.baseAddr +
256 (pt_entry.index << pt_entry.shift)) {
257 pt_entry.indirectCounter++;
258 pt_entry.increasedIndirectCounter = true;
259 }
260 }
261 }
262}
263
264} // namespace prefetch
265} // 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 - 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
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 Tue Jun 18 2024 16:24:05 for gem5 by doxygen 1.11.0