gem5  [DEVELOP-FOR-23.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 
35 namespace gem5
36 {
37 
38 namespace prefetch
39 {
40 
41 IndirectMemory::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 
57 void
59  std::vector<AddrPriority> &addresses)
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
130  allocateOrUpdateIPDEntry(pt_entry, index);
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 *
145  pt_entry->indirectCounter.calcSaturation();
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 
165 void
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 
195 void
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 }
214 void
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 
247 void
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
gem5::prefetch::Base::PrefetchInfo::getAddr
Addr getAddr() const
Obtains the address value of this Prefetcher address.
Definition: base.hh:124
associative_set_impl.hh
gem5::prefetch::IndirectMemory::shiftValues
const std::vector< int > shiftValues
Shift values considered.
Definition: indirect_memory.hh:61
gem5::GenericSatCounter::calcSaturation
double calcSaturation() const
Calculate saturation percentile of the current counter's value with regard to its maximum possible va...
Definition: sat_counter.hh:303
gem5::prefetch::IndirectMemory::PrefetchTableEntry::baseAddr
Addr baseAddr
BaseAddr detected.
Definition: indirect_memory.hh:88
base.hh
gem5::prefetch::Queued::AddrPriority
std::pair< Addr, int32_t > AddrPriority
Definition: queued.hh:190
gem5::prefetch::IndirectMemory::IndirectMemory
IndirectMemory(const IndirectMemoryPrefetcherParams &p)
Definition: indirect_memory.cc:41
gem5::MipsISA::index
Bitfield< 30, 0 > index
Definition: pra_constants.hh:47
gem5::prefetch::IndirectMemory::PrefetchTableEntry::shift
int shift
Shift detected.
Definition: indirect_memory.hh:90
gem5::prefetch::Base::PrefetchInfo::isSecure
bool isSecure() const
Returns true if the address targets the secure memory space.
Definition: base.hh:133
gem5::prefetch::IndirectMemory::streamingDistance
const int streamingDistance
Number of prefetches generated when using the streaming prefetcher.
Definition: indirect_memory.hh:67
gem5::prefetch::IndirectMemory::IndirectPatternDetectorEntry::idx2
int64_t idx2
Second index.
Definition: indirect_memory.hh:132
gem5::prefetch::IndirectMemory::prefetchThreshold
const unsigned int prefetchThreshold
Counter threshold to start prefetching.
Definition: indirect_memory.hh:63
gem5::prefetch::IndirectMemory::prefetchTable
AssociativeSet< PrefetchTableEntry > prefetchTable
Prefetch table.
Definition: indirect_memory.hh:124
gem5::prefetch::Base::PrefetchInfo::isCacheMiss
bool isCacheMiss() const
Check if this event comes from a cache miss.
Definition: base.hh:198
gem5::ArmISA::byteOrder
ByteOrder byteOrder(const ThreadContext *tc)
Definition: utility.hh:357
std::vector
STL vector class.
Definition: stl.hh:37
gem5::TaggedEntry::getTag
virtual Addr getTag() const
Get tag associated to this block.
Definition: tagged_entry.hh:71
gem5::prefetch::IndirectMemory::ipdEntryTrackingMisses
IndirectPatternDetectorEntry * ipdEntryTrackingMisses
Entry currently tracking misses.
Definition: indirect_memory.hh:166
gem5::prefetch::Base::PrefetchInfo::get
T get(ByteOrder endian) const
Gets the associated data of the request triggering the event.
Definition: base.hh:210
gem5::ArmISA::i
Bitfield< 7 > i
Definition: misc_types.hh:67
gem5::prefetch::IndirectMemory::PrefetchTableEntry::streamCounter
unsigned int streamCounter
Confidence counter of the stream.
Definition: indirect_memory.hh:79
gem5::prefetch::IndirectMemory::IndirectPatternDetectorEntry::secondIndexSet
bool secondIndexSet
Valid bit for the second index.
Definition: indirect_memory.hh:134
indirect_memory.hh
gem5::prefetch::IndirectMemory::streamCounterThreshold
const int streamCounterThreshold
streamCounter value to trigger the streaming prefetcher
Definition: indirect_memory.hh:65
gem5::prefetch::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:215
gem5::ArmISA::shift
Bitfield< 6, 5 > shift
Definition: types.hh:117
gem5::prefetch::Base::PrefetchInfo::getPC
Addr getPC() const
Returns the program counter that generated this request.
Definition: base.hh:142
gem5::prefetch::IndirectMemory::ipd
AssociativeSet< IndirectPatternDetectorEntry > ipd
Indirect Pattern Detector (IPD) table.
Definition: indirect_memory.hh:163
gem5::VegaISA::p
Bitfield< 54 > p
Definition: pagetable.hh:70
gem5::prefetch::IndirectMemory::PrefetchTableEntry::address
Addr address
Accessed address.
Definition: indirect_memory.hh:75
gem5::prefetch::IndirectMemory::PrefetchTableEntry::enabled
bool enabled
Enable bit of the indirect fields.
Definition: indirect_memory.hh:84
gem5::prefetch::IndirectMemory::IndirectPatternDetectorEntry
Indirect Pattern Detector entrt.
Definition: indirect_memory.hh:127
gem5::GenericSatCounter::reset
void reset()
Reset the counter to its initial value.
Definition: sat_counter.hh:292
gem5::prefetch::IndirectMemory::IndirectPatternDetectorEntry::idx1
int64_t idx1
First index.
Definition: indirect_memory.hh:130
gem5::prefetch::IndirectMemory::PrefetchTableEntry
Prefetch Table Entry.
Definition: indirect_memory.hh:70
gem5::Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
gem5::prefetch::IndirectMemory::maxPrefetchDistance
const unsigned int maxPrefetchDistance
Maximum number of prefetches generated per event.
Definition: indirect_memory.hh:59
gem5::prefetch::IndirectMemory::allocateOrUpdateIPDEntry
void allocateOrUpdateIPDEntry(const PrefetchTableEntry *pt_entry, int64_t index)
Allocate or update an entry in the IPD.
Definition: indirect_memory.cc:166
gem5::prefetch::Base::PrefetchInfo::isWrite
bool isWrite() const
Checks if the request that caused this prefetch event was a write request.
Definition: base.hh:180
gem5::prefetch::IndirectMemory::PrefetchTableEntry::indirectCounter
SatCounter8 indirectCounter
Confidence counter of the indirect fields.
Definition: indirect_memory.hh:92
gem5::prefetch::Base::PrefetchInfo::getSize
unsigned int getSize() const
Gets the size of the request triggering this event.
Definition: base.hh:170
gem5::prefetch::Queued
Definition: queued.hh:59
gem5::prefetch::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:99
gem5::prefetch::IndirectMemory::PrefetchTableEntry::secure
bool secure
Whether this address is in the secure region.
Definition: indirect_memory.hh:77
gem5::prefetch::IndirectMemory::PrefetchTableEntry::index
int64_t index
Current index value.
Definition: indirect_memory.hh:86
gem5::MipsISA::pc
Bitfield< 4 > pc
Definition: pra_constants.hh:243
gem5::prefetch::IndirectMemory::IndirectPatternDetectorEntry::numMisses
int numMisses
Number of misses currently recorded.
Definition: indirect_memory.hh:136
gem5::prefetch::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:248
gem5::prefetch::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:196
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: gpu_translation_state.hh:37
gem5::prefetch::IndirectMemory::IndirectPatternDetectorEntry::baseAddr
std::vector< std::vector< Addr > > baseAddr
Potential BaseAddr candidates for each recorded miss.
Definition: indirect_memory.hh:142
gem5::prefetch::IndirectMemory::byteOrder
const ByteOrder byteOrder
Byte order used to access the cache.
Definition: indirect_memory.hh:169
gem5::prefetch::IndirectMemory::calculatePrefetch
void calculatePrefetch(const PrefetchInfo &pfi, std::vector< AddrPriority > &addresses) override
Definition: indirect_memory.cc:58
gem5::prefetch::Base::PrefetchInfo
Class containing the information needed by the prefetch to train and generate new prefetch requests.
Definition: base.hh:96
gem5::X86ISA::addr
Bitfield< 3 > addr
Definition: types.hh:84
gem5::prefetch::Base::PrefetchInfo::hasPC
bool hasPC() const
Returns true if the associated program counter is valid.
Definition: base.hh:152

Generated on Sun Jul 30 2023 01:56:57 for gem5 by doxygen 1.8.17