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

Generated on Wed Sep 30 2020 14:02:12 for gem5 by doxygen 1.8.17