gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
stride.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012-2013, 2015 ARM Limited
3  * All rights reserved
4  *
5  * The license below extends only to copyright in the software and shall
6  * not be construed as granting a license to any other intellectual
7  * property including but not limited to intellectual property relating
8  * to a hardware implementation of the functionality of the software
9  * licensed hereunder. You may use the software subject to the license
10  * terms below provided that you ensure that this notice is replicated
11  * unmodified and in its entirety in all distributions of the software,
12  * modified or unmodified, in source code or in binary form.
13  *
14  * Copyright (c) 2005 The Regents of The University of Michigan
15  * All rights reserved.
16  *
17  * Redistribution and use in source and binary forms, with or without
18  * modification, are permitted provided that the following conditions are
19  * met: redistributions of source code must retain the above copyright
20  * notice, this list of conditions and the following disclaimer;
21  * redistributions in binary form must reproduce the above copyright
22  * notice, this list of conditions and the following disclaimer in the
23  * documentation and/or other materials provided with the distribution;
24  * neither the name of the copyright holders nor the names of its
25  * contributors may be used to endorse or promote products derived from
26  * this software without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39  *
40  * Authors: Ron Dreslinski
41  * Steve Reinhardt
42  */
43 
50 
51 #include "base/random.hh"
52 #include "base/trace.hh"
53 #include "debug/HWPrefetch.hh"
54 
55 StridePrefetcher::StridePrefetcher(const StridePrefetcherParams *p)
56  : QueuedPrefetcher(p),
57  maxConf(p->max_conf),
58  threshConf(p->thresh_conf),
59  minConf(p->min_conf),
60  startConf(p->start_conf),
61  pcTableAssoc(p->table_assoc),
62  pcTableSets(p->table_sets),
63  useMasterId(p->use_master_id),
64  degree(p->degree),
65  pcTable(pcTableAssoc, pcTableSets, name())
66 {
67  // Don't consult stride prefetcher on instruction accesses
68  onInst = false;
69 
70  assert(isPowerOf2(pcTableSets));
71 }
72 
75 {
76  auto res = entries.insert(std::make_pair(context,
77  new StrideEntry*[pcTableSets]));
78  auto it = res.first;
79  chatty_assert(res.second, "Allocating an already created context\n");
80  assert(it->first == context);
81 
82  DPRINTF(HWPrefetch, "Adding context %i with stride entries at %p\n",
83  context, it->second);
84 
85  StrideEntry** entry = it->second;
86  for (int s = 0; s < pcTableSets; s++) {
87  entry[s] = new StrideEntry[pcTableAssoc];
88  }
89  return entry;
90 }
91 
93  for (auto entry : entries) {
94  for (int s = 0; s < pcTableSets; s++) {
95  delete[] entry.second[s];
96  }
97  delete[] entry.second;
98  }
99 }
100 
101 void
103  std::vector<AddrPriority> &addresses)
104 {
105  if (!pkt->req->hasPC()) {
106  DPRINTF(HWPrefetch, "Ignoring request with no PC.\n");
107  return;
108  }
109 
110  // Get required packet info
111  Addr pkt_addr = pkt->getAddr();
112  Addr pc = pkt->req->getPC();
113  bool is_secure = pkt->isSecure();
114  MasterID master_id = useMasterId ? pkt->req->masterId() : 0;
115 
116  // Lookup pc-based information
117  StrideEntry *entry;
118 
119  if (pcTableHit(pc, is_secure, master_id, entry)) {
120  // Hit in table
121  int new_stride = pkt_addr - entry->lastAddr;
122  bool stride_match = (new_stride == entry->stride);
123 
124  // Adjust confidence for stride entry
125  if (stride_match && new_stride != 0) {
126  if (entry->confidence < maxConf)
127  entry->confidence++;
128  } else {
129  if (entry->confidence > minConf)
130  entry->confidence--;
131  // If confidence has dropped below the threshold, train new stride
132  if (entry->confidence < threshConf)
133  entry->stride = new_stride;
134  }
135 
136  DPRINTF(HWPrefetch, "Hit: PC %x pkt_addr %x (%s) stride %d (%s), "
137  "conf %d\n", pc, pkt_addr, is_secure ? "s" : "ns", new_stride,
138  stride_match ? "match" : "change",
139  entry->confidence);
140 
141  entry->lastAddr = pkt_addr;
142 
143  // Abort prefetch generation if below confidence threshold
144  if (entry->confidence < threshConf)
145  return;
146 
147  // Generate up to degree prefetches
148  for (int d = 1; d <= degree; d++) {
149  // Round strides up to atleast 1 cacheline
150  int prefetch_stride = new_stride;
151  if (abs(new_stride) < blkSize) {
152  prefetch_stride = (new_stride < 0) ? -blkSize : blkSize;
153  }
154 
155  Addr new_addr = pkt_addr + d * prefetch_stride;
156  if (samePage(pkt_addr, new_addr)) {
157  DPRINTF(HWPrefetch, "Queuing prefetch to %#x.\n", new_addr);
158  addresses.push_back(AddrPriority(new_addr, 0));
159  } else {
160  // Record the number of page crossing prefetches generated
161  pfSpanPage += degree - d + 1;
162  DPRINTF(HWPrefetch, "Ignoring page crossing prefetch.\n");
163  return;
164  }
165  }
166  } else {
167  // Miss in table
168  DPRINTF(HWPrefetch, "Miss: PC %x pkt_addr %x (%s)\n", pc, pkt_addr,
169  is_secure ? "s" : "ns");
170 
171  StrideEntry* entry = pcTableVictim(pc, master_id);
172  entry->instAddr = pc;
173  entry->lastAddr = pkt_addr;
174  entry->isSecure= is_secure;
175  entry->stride = 0;
176  entry->confidence = startConf;
177  }
178 }
179 
180 inline Addr
182 {
183  Addr hash1 = pc >> 1;
184  Addr hash2 = hash1 >> floorLog2(pcTableSets);
185  return (hash1 ^ hash2) & (Addr)(pcTableSets - 1);
186 }
187 
190 {
191  // Rand replacement for now
192  int set = pcHash(pc);
193  int way = random_mt.random<int>(0, pcTableAssoc - 1);
194 
195  DPRINTF(HWPrefetch, "Victimizing lookup table[%d][%d].\n", set, way);
196  return &pcTable[master_id][set][way];
197 }
198 
199 inline bool
200 StridePrefetcher::pcTableHit(Addr pc, bool is_secure, int master_id,
201  StrideEntry* &entry)
202 {
203  int set = pcHash(pc);
204  StrideEntry* set_entries = pcTable[master_id][set];
205  for (int way = 0; way < pcTableAssoc; way++) {
206  // Search ways for match
207  if (set_entries[way].instAddr == pc &&
208  set_entries[way].isSecure == is_secure) {
209  DPRINTF(HWPrefetch, "Lookup hit table[%d][%d].\n", set, way);
210  entry = &set_entries[way];
211  return true;
212  }
213  }
214  return false;
215 }
216 
218 StridePrefetcherParams::create()
219 {
220  return new StridePrefetcher(this);
221 }
#define chatty_assert(cond,...)
The chatty assert macro will function like a normal assert, but will allow the specification of addit...
Definition: misc.hh:259
bool isSecure() const
Definition: packet.hh:661
#define DPRINTF(x,...)
Definition: trace.hh:212
const int degree
Definition: stride.hh:69
const std::string & name()
Definition: trace.cc:49
PCTable pcTable
Definition: stride.hh:107
StridePrefetcher(const StridePrefetcherParams *p)
Definition: stride.cc:55
StrideEntry * pcTableVictim(Addr pc, int master_id)
Definition: stride.cc:189
bool hasPC() const
Definition: request.hh:708
Addr getPC() const
Accessor function for pc.
Definition: request.hh:715
const int startConf
Definition: stride.hh:62
Addr pcHash(Addr pc) const
Definition: stride.cc:181
STL vector class.
Definition: stl.hh:40
std::enable_if< std::is_integral< T >::value, T >::type random()
Use the SFINAE idiom to choose an implementation based on whether the type is integral or floating po...
Definition: random.hh:83
Describes a strided prefetcher.
std::pair< Addr, int32_t > AddrPriority
Definition: queued.hh:70
Bitfield< 4 > s
Definition: miscregs.hh:1738
const bool useMasterId
Definition: stride.hh:67
const int pcTableSets
Definition: stride.hh:65
Bitfield< 9 > d
Definition: miscregs.hh:1375
const RequestPtr req
A pointer to the original request.
Definition: packet.hh:304
bool isPowerOf2(const T &n)
Definition: intmath.hh:73
const int minConf
Definition: stride.hh:61
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:85
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
Definition: packet.hh:245
bool pcTableHit(Addr pc, bool is_secure, int master_id, StrideEntry *&entry)
Definition: stride.cc:200
MasterID masterId() const
Accesssor for the requestor id.
Definition: request.hh:624
void calculatePrefetch(const PacketPtr &pkt, std::vector< AddrPriority > &addresses)
Definition: stride.cc:102
int floorLog2(unsigned x)
Definition: intmath.hh:100
Stats::Scalar pfSpanPage
Definition: queued.hh:106
Random random_mt
Definition: random.cc:100
const int threshConf
Definition: stride.hh:60
bool onInst
Consult prefetcher on instruction accesses?
Definition: base.hh:90
IntReg pc
Definition: remote_gdb.hh:91
StrideEntry ** allocateNewContext(int context)
Definition: stride.cc:74
unsigned blkSize
The block size of the parent cache.
Definition: base.hh:69
Bitfield< 0 > p
std::unordered_map< int, StrideEntry ** > entries
Definition: stride.hh:103
bool samePage(Addr a, Addr b) const
Determine if addresses are on the same page.
Definition: base.cc:131
const int pcTableAssoc
Definition: stride.hh:64
Addr getAddr() const
Definition: packet.hh:639
const int maxConf
Definition: stride.hh:59

Generated on Fri Jun 9 2017 13:03:48 for gem5 by doxygen 1.8.6