gem5 v23.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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(p.pt_table_assoc, p.pt_table_entries,
48 p.pt_table_indexing_policy, p.pt_table_replacement_policy,
49 PrefetchTableEntry(p.num_indirect_counter_bits)),
50 ipd(p.ipd_table_assoc, p.ipd_table_entries, p.ipd_table_indexing_policy,
51 p.ipd_table_replacement_policy,
52 IndirectPatternDetectorEntry(p.addr_array_len, shiftValues.size())),
53 ipdEntryTrackingMisses(nullptr), byteOrder(p.sys->getGuestByteOrder())
54{
55}
56
57void
60{
61 // This prefetcher requires a PC
62 if (!pfi.hasPC()) {
63 return;
64 }
65
66 bool is_secure = pfi.isSecure();
67 Addr pc = pfi.getPC();
68 Addr addr = pfi.getAddr();
69 bool miss = pfi.isCacheMiss();
70
72
73 // First check if this is a miss, if the prefetcher is tracking misses
74 if (ipdEntryTrackingMisses != nullptr && miss) {
75 // Check if the entry tracking misses has already set its second index
78 } else {
80 }
81 } else {
82 // if misses are not being tracked, attempt to detect stream accesses
83 PrefetchTableEntry *pt_entry =
84 prefetchTable.findEntry(pc, false /* unused */);
85 if (pt_entry != nullptr) {
86 prefetchTable.accessEntry(pt_entry);
87
88 if (pt_entry->address != addr) {
89 // Streaming access found
90 pt_entry->streamCounter += 1;
91 if (pt_entry->streamCounter >= streamCounterThreshold) {
92 int64_t delta = addr - pt_entry->address;
93 for (unsigned int i = 1; i <= streamingDistance; i += 1) {
94 addresses.push_back(AddrPriority(addr + delta * i, 0));
95 }
96 }
97 pt_entry->address = addr;
98 pt_entry->secure = is_secure;
99
100
101 // if this is a read, read the data from the cache and assume
102 // it is an index (this is only possible if the data is already
103 // in the cache), also, only indexes up to 8 bytes are
104 // considered
105
106 if (!miss && !pfi.isWrite() && pfi.getSize() <= 8) {
107 int64_t index = 0;
108 bool read_index = true;
109 switch(pfi.getSize()) {
110 case sizeof(uint8_t):
111 index = pfi.get<uint8_t>(byteOrder);
112 break;
113 case sizeof(uint16_t):
114 index = pfi.get<uint16_t>(byteOrder);
115 break;
116 case sizeof(uint32_t):
117 index = pfi.get<uint32_t>(byteOrder);
118 break;
119 case sizeof(uint64_t):
120 index = pfi.get<uint64_t>(byteOrder);
121 break;
122 default:
123 // Ignore non-power-of-two sizes
124 read_index = false;
125 }
126 if (read_index && !pt_entry->enabled) {
127 // Not enabled (no pattern detected in this stream),
128 // add or update an entry in the pattern detector and
129 // start tracking misses
131 } else if (read_index) {
132 // Enabled entry, update the index
133 pt_entry->index = index;
134 if (!pt_entry->increasedIndirectCounter) {
135 pt_entry->indirectCounter--;
136 } else {
137 // Set this to false, to see if the new index
138 // has any match
139 pt_entry->increasedIndirectCounter = false;
140 }
141
142 // If the counter is high enough, start prefetching
143 if (pt_entry->indirectCounter > prefetchThreshold) {
144 unsigned distance = maxPrefetchDistance *
146 for (int delta = 1; delta < distance; delta += 1) {
147 Addr pf_addr = pt_entry->baseAddr +
148 (pt_entry->index << pt_entry->shift);
149 addresses.push_back(AddrPriority(pf_addr, 0));
150 }
151 }
152 }
153 }
154 }
155 } else {
156 pt_entry = prefetchTable.findVictim(pc);
157 assert(pt_entry != nullptr);
158 prefetchTable.insertEntry(pc, false /* unused */, pt_entry);
159 pt_entry->address = addr;
160 pt_entry->secure = is_secure;
161 }
162 }
163}
164
165void
167 const PrefetchTableEntry *pt_entry, int64_t index)
168{
169 // The address of the pt_entry is used to index the IPD
170 Addr ipd_entry_addr = (Addr) pt_entry;
171 IndirectPatternDetectorEntry *ipd_entry = ipd.findEntry(ipd_entry_addr,
172 false/* unused */);
173 if (ipd_entry != nullptr) {
174 ipd.accessEntry(ipd_entry);
175 if (!ipd_entry->secondIndexSet) {
176 // Second time we see an index, fill idx2
177 ipd_entry->idx2 = index;
178 ipd_entry->secondIndexSet = true;
179 ipdEntryTrackingMisses = ipd_entry;
180 } else {
181 // Third access! no pattern has been found so far,
182 // release the IPD entry
183 ipd.invalidate(ipd_entry);
184 ipdEntryTrackingMisses = nullptr;
185 }
186 } else {
187 ipd_entry = ipd.findVictim(ipd_entry_addr);
188 assert(ipd_entry != nullptr);
189 ipd.insertEntry(ipd_entry_addr, false /* unused */, ipd_entry);
190 ipd_entry->idx1 = index;
191 ipdEntryTrackingMisses = ipd_entry;
192 }
193}
194
195void
197{
199 // If the second index is not set, we are just filling the baseAddr
200 // vector
201 assert(entry->numMisses < entry->baseAddr.size());
202 std::vector<Addr> &ba_array = entry->baseAddr[entry->numMisses];
203 int idx = 0;
204 for (int shift : shiftValues) {
205 ba_array[idx] = miss_addr - (entry->idx1 << shift);
206 idx += 1;
207 }
208 entry->numMisses += 1;
209 if (entry->numMisses == entry->baseAddr.size()) {
210 // stop tracking misses once we have tracked enough
211 ipdEntryTrackingMisses = nullptr;
212 }
213}
214void
216{
218 // Second index is filled, compare the addresses generated during
219 // the previous misses (using idx1) against newly generated values
220 // using idx2, if a match is found, fill the additional fields
221 // of the PT entry
222 for (int midx = 0; midx < entry->numMisses; midx += 1)
223 {
224 std::vector<Addr> &ba_array = entry->baseAddr[midx];
225 int idx = 0;
226 for (int shift : shiftValues) {
227 if (ba_array[idx] == (miss_addr - (entry->idx2 << shift))) {
228 // Match found!
229 // Fill the corresponding pt_entry
230 PrefetchTableEntry *pt_entry =
231 (PrefetchTableEntry *) entry->getTag();
232 pt_entry->baseAddr = ba_array[idx];
233 pt_entry->shift = shift;
234 pt_entry->enabled = true;
235 pt_entry->indirectCounter.reset();
236 // Release the current IPD Entry
237 ipd.invalidate(entry);
238 // Do not track more misses
239 ipdEntryTrackingMisses = nullptr;
240 return;
241 }
242 idx += 1;
243 }
244 }
245}
246
247void
249{
250 for (auto &pt_entry : prefetchTable) {
251 if (pt_entry.enabled) {
252 if (addr == pt_entry.baseAddr +
253 (pt_entry.index << pt_entry.shift)) {
254 pt_entry.indirectCounter++;
255 pt_entry.increasedIndirectCounter = true;
256 }
257 }
258 }
259}
260
261} // namespace prefetch
262} // 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:97
Addr getPC() const
Returns the program counter that generated this request.
Definition base.hh:142
bool isSecure() const
Returns true if the address targets the secure memory space.
Definition base.hh:133
unsigned int getSize() const
Gets the size of the request triggering this event.
Definition base.hh:170
bool isWrite() const
Checks if the request that caused this prefetch event was a write request.
Definition base.hh:180
bool isCacheMiss() const
Check if this event comes from a cache miss.
Definition base.hh:198
Addr getAddr() const
Obtains the address value of this Prefetcher address.
Definition base.hh:124
T get(ByteOrder endian) const
Gets the associated data of the request triggering the event.
Definition base.hh:210
bool hasPC() const
Returns true if the associated program counter is valid.
Definition base.hh:152
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.
AssociativeSet< PrefetchTableEntry > prefetchTable
Prefetch 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.
void calculatePrefetch(const PrefetchInfo &pfi, std::vector< AddrPriority > &addresses) override
AssociativeSet< IndirectPatternDetectorEntry > ipd
Indirect Pattern Detector (IPD) table.
IndirectPatternDetectorEntry * ipdEntryTrackingMisses
Entry currently tracking misses.
const int streamingDistance
Number of prefetches generated when using the streaming prefetcher.
const unsigned int prefetchThreshold
Counter threshold to start prefetching.
IndirectMemory(const IndirectMemoryPrefetcherParams &p)
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:190
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:357
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
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
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.

Generated on Mon Jul 10 2023 14:24:32 for gem5 by doxygen 1.9.7