gem5  v19.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
stride.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018 Inria
3  * Copyright (c) 2012-2013, 2015 ARM Limited
4  * All rights reserved
5  *
6  * The license below extends only to copyright in the software and shall
7  * not be construed as granting a license to any other intellectual
8  * property including but not limited to intellectual property relating
9  * to a hardware implementation of the functionality of the software
10  * licensed hereunder. You may use the software subject to the license
11  * terms below provided that you ensure that this notice is replicated
12  * unmodified and in its entirety in all distributions of the software,
13  * modified or unmodified, in source code or in binary form.
14  *
15  * Copyright (c) 2005 The Regents of The University of Michigan
16  * All rights reserved.
17  *
18  * Redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions are
20  * met: redistributions of source code must retain the above copyright
21  * notice, this list of conditions and the following disclaimer;
22  * redistributions in binary form must reproduce the above copyright
23  * notice, this list of conditions and the following disclaimer in the
24  * documentation and/or other materials provided with the distribution;
25  * neither the name of the copyright holders nor the names of its
26  * contributors may be used to endorse or promote products derived from
27  * this software without specific prior written permission.
28  *
29  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40  *
41  * Authors: Ron Dreslinski
42  * Steve Reinhardt
43  * Daniel Carvalho
44  */
45 
52 
53 #include <cassert>
54 
55 #include "base/intmath.hh"
56 #include "base/logging.hh"
57 #include "base/random.hh"
58 #include "base/trace.hh"
59 #include "debug/HWPrefetch.hh"
61 #include "params/StridePrefetcher.hh"
62 
64 {
65  invalidate();
66 }
67 
68 void
70 {
71  instAddr = 0;
72  lastAddr = 0;
73  isSecure = false;
74  stride = 0;
75  confidence = 0;
76 }
77 
78 StridePrefetcher::StridePrefetcher(const StridePrefetcherParams *p)
79  : QueuedPrefetcher(p),
80  maxConf(p->max_conf),
81  threshConf(p->thresh_conf),
82  minConf(p->min_conf),
83  startConf(p->start_conf),
84  pcTableAssoc(p->table_assoc),
85  pcTableSets(p->table_sets),
86  useMasterId(p->use_master_id),
87  degree(p->degree),
88  replacementPolicy(p->replacement_policy)
89 {
90  assert(isPowerOf2(pcTableSets));
91 }
92 
95 {
96  // Check if table for given context exists
97  auto it = pcTables.find(context);
98  if (it != pcTables.end())
99  return &it->second;
100 
101  // If table does not exist yet, create one
102  return allocateNewContext(context);
103 }
104 
107 {
108  // Create new table
109  auto insertion_result = pcTables.insert(std::make_pair(context,
111 
112  DPRINTF(HWPrefetch, "Adding context %i with stride entries\n", context);
113 
114  // Get iterator to new pc table, and then return a pointer to the new table
115  return &(insertion_result.first->second);
116 }
117 
118 StridePrefetcher::PCTable::PCTable(int assoc, int sets, const std::string name,
120  : pcTableSets(sets), _name(name), entries(pcTableSets),
121  replacementPolicy(replacementPolicy)
122 {
123  for (int set = 0; set < sets; set++) {
124  entries[set].resize(assoc);
125  for (int way = 0; way < assoc; way++) {
126  // Inform the entry its position
127  entries[set][way].setPosition(set, way);
128 
129  // Initialize replacement policy data
130  entries[set][way].replacementData =
131  replacementPolicy->instantiateEntry();
132  }
133  }
134 }
135 
137 {
138 }
139 
140 void
142  std::vector<AddrPriority> &addresses)
143 {
144  if (!pfi.hasPC()) {
145  DPRINTF(HWPrefetch, "Ignoring request with no PC.\n");
146  return;
147  }
148 
149  // Get required packet info
150  Addr pf_addr = pfi.getAddr();
151  Addr pc = pfi.getPC();
152  bool is_secure = pfi.isSecure();
153  MasterID master_id = useMasterId ? pfi.getMasterId() : 0;
154 
155  // Get corresponding pc table
156  PCTable* pcTable = findTable(master_id);
157 
158  // Search for entry in the pc table
159  StrideEntry *entry = pcTable->findEntry(pc, is_secure);
160 
161  if (entry != nullptr) {
162  // Hit in table
163  int new_stride = pf_addr - entry->lastAddr;
164  bool stride_match = (new_stride == entry->stride);
165 
166  // Adjust confidence for stride entry
167  if (stride_match && new_stride != 0) {
168  if (entry->confidence < maxConf)
169  entry->confidence++;
170  } else {
171  if (entry->confidence > minConf)
172  entry->confidence--;
173  // If confidence has dropped below the threshold, train new stride
174  if (entry->confidence < threshConf)
175  entry->stride = new_stride;
176  }
177 
178  DPRINTF(HWPrefetch, "Hit: PC %x pkt_addr %x (%s) stride %d (%s), "
179  "conf %d\n", pc, pf_addr, is_secure ? "s" : "ns",
180  new_stride, stride_match ? "match" : "change",
181  entry->confidence);
182 
183  entry->lastAddr = pf_addr;
184 
185  // Abort prefetch generation if below confidence threshold
186  if (entry->confidence < threshConf)
187  return;
188 
189  // Generate up to degree prefetches
190  for (int d = 1; d <= degree; d++) {
191  // Round strides up to atleast 1 cacheline
192  int prefetch_stride = new_stride;
193  if (abs(new_stride) < blkSize) {
194  prefetch_stride = (new_stride < 0) ? -blkSize : blkSize;
195  }
196 
197  Addr new_addr = pf_addr + d * prefetch_stride;
198  addresses.push_back(AddrPriority(new_addr, 0));
199  }
200  } else {
201  // Miss in table
202  DPRINTF(HWPrefetch, "Miss: PC %x pkt_addr %x (%s)\n", pc, pf_addr,
203  is_secure ? "s" : "ns");
204 
205  StrideEntry* entry = pcTable->findVictim(pc);
206 
207  // Invalidate victim
208  entry->invalidate();
210 
211  // Insert new entry's data
212  entry->instAddr = pc;
213  entry->lastAddr = pf_addr;
214  entry->isSecure = is_secure;
215  entry->confidence = startConf;
217  }
218 }
219 
220 inline Addr
222 {
223  Addr hash1 = pc >> 1;
224  Addr hash2 = hash1 >> floorLog2(pcTableSets);
225  return (hash1 ^ hash2) & (Addr)(pcTableSets - 1);
226 }
227 
230 {
231  // Rand replacement for now
232  int set = pcHash(pc);
233 
234  // Get possible entries to be victimized
235  std::vector<ReplaceableEntry*> possible_entries;
236  for (auto& entry : entries[set]) {
237  possible_entries.push_back(&entry);
238  }
239 
240  // Choose victim based on replacement policy
241  StrideEntry* victim = static_cast<StrideEntry*>(
242  replacementPolicy->getVictim(possible_entries));
243 
244  DPRINTF(HWPrefetch, "Victimizing lookup table[%d][%d].\n",
245  victim->getSet(), victim->getWay());
246 
247  return victim;
248 }
249 
252 {
253  int set = pcHash(pc);
254  for (auto& entry : entries[set]) {
255  // Search ways for match
256  if ((entry.instAddr == pc) && (entry.isSecure == is_secure)) {
257  DPRINTF(HWPrefetch, "Lookup hit table[%d][%d].\n", entry.getSet(),
258  entry.getWay());
259  replacementPolicy->touch(entry.replacementData);
260  return &entry;
261  }
262  }
263  return nullptr;
264 }
265 
267 StridePrefetcherParams::create()
268 {
269  return new StridePrefetcher(this);
270 }
#define DPRINTF(x,...)
Definition: trace.hh:229
const int degree
Definition: stride.hh:78
PCTable * allocateNewContext(int context)
Create a PC table for the given context.
Definition: stride.cc:106
void invalidate()
Invalidate the entry.
Definition: stride.cc:69
Addr pcHash(Addr pc) const
PC hashing function to index sets in the table.
Definition: stride.cc:221
StridePrefetcher(const StridePrefetcherParams *p)
Definition: stride.cc:78
virtual void touch(const std::shared_ptr< ReplacementData > &replacement_data) const =0
Update replacement data.
bool isSecure() const
Returns true if the address targets the secure memory space.
Definition: base.hh:128
virtual ReplaceableEntry * getVictim(const ReplacementCandidates &candidates) const =0
Find replacement victim among candidates.
const int startConf
Definition: stride.hh:71
BaseReplacementPolicy * replacementPolicy
Replacement policy used in the PC tables.
Definition: stride.hh:81
A common base class of cache replacement policy objects.
Definition: base.hh:48
STL vector class.
Definition: stl.hh:40
void calculatePrefetch(const PrefetchInfo &pfi, std::vector< AddrPriority > &addresses) override
Definition: stride.cc:141
Describes a strided prefetcher.
Addr getAddr() const
Obtains the address value of this Prefetcher address.
Definition: base.hh:119
Bitfield< 4 > pc
Class containing the information needed by the prefetch to train and generate new prefetch requests...
Definition: base.hh:92
std::pair< Addr, int32_t > AddrPriority
Definition: queued.hh:178
const bool useMasterId
Definition: stride.hh:76
std::shared_ptr< ReplacementData > replacementData
Replacement data associated to this entry.
Addr getPC() const
Returns the program counter that generated this request.
Definition: base.hh:137
const int pcTableSets
Definition: stride.hh:74
std::vector< std::vector< StrideEntry > > entries
Definition: stride.hh:138
Bitfield< 9 > d
bool isPowerOf2(const T &n)
Definition: intmath.hh:146
StrideEntry * findEntry(Addr pc, bool is_secure)
Search for an entry in the pc table.
Definition: stride.cc:251
~PCTable()
Default destructor.
Definition: stride.cc:136
const int minConf
Definition: stride.hh:70
PCTable(int assoc, int sets, const std::string name, BaseReplacementPolicy *replacementPolicy)
Default constructor.
Definition: stride.cc:118
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
uint16_t MasterID
Definition: request.hh:86
virtual const std::string name() const
Definition: sim_object.hh:120
virtual std::shared_ptr< ReplacementData > instantiateEntry()=0
Instantiate a replacement data entry.
PCTable * findTable(int context)
Try to find a table of entries for the given context.
Definition: stride.cc:94
StrideEntry()
Default constructor.
Definition: stride.cc:63
virtual void invalidate(const std::shared_ptr< ReplacementData > &replacement_data) const =0
Invalidate replacement data to set it as the next probable victim.
virtual void reset(const std::shared_ptr< ReplacementData > &replacement_data) const =0
Reset replacement data.
int floorLog2(unsigned x)
Definition: intmath.hh:61
uint32_t getWay() const
Get way number.
StrideEntry * findVictim(Addr pc)
Find a replacement victim to make room for given PC.
Definition: stride.cc:229
std::unordered_map< int, PCTable > pcTables
Definition: stride.hh:153
const int threshConf
Definition: stride.hh:69
uint32_t getSet() const
Get set number.
unsigned blkSize
The block size of the parent cache.
Definition: base.hh:264
Bitfield< 0 > p
BaseReplacementPolicy * replacementPolicy
Replacement policy used by StridePrefetcher.
Definition: stride.hh:143
const int pcTableAssoc
Definition: stride.hh:73
const int maxConf
Definition: stride.hh:68
MasterID getMasterId() const
Gets the requestor ID that generated this address.
Definition: base.hh:156
bool hasPC() const
Returns true if the associated program counter is valid.
Definition: base.hh:147

Generated on Fri Feb 28 2020 16:27:01 for gem5 by doxygen 1.8.13