gem5  v20.1.0.0
loop_predictor.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 The University of Wisconsin
3  *
4  * Copyright (c) 2006 INRIA (Institut National de Recherche en
5  * Informatique et en Automatique / French National Research Institute
6  * for Computer Science and Applied Mathematics)
7  *
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions are
12  * met: redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer;
14  * redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in the
16  * documentation and/or other materials provided with the distribution;
17  * neither the name of the copyright holders nor the names of its
18  * contributors may be used to endorse or promote products derived from
19  * this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
35 
36 #include "base/random.hh"
37 #include "base/trace.hh"
38 #include "debug/LTage.hh"
39 #include "params/LoopPredictor.hh"
40 
41 LoopPredictor::LoopPredictor(LoopPredictorParams *p)
42  : SimObject(p), logSizeLoopPred(p->logSizeLoopPred),
43  loopTableAgeBits(p->loopTableAgeBits),
44  loopTableConfidenceBits(p->loopTableConfidenceBits),
45  loopTableTagBits(p->loopTableTagBits),
46  loopTableIterBits(p->loopTableIterBits),
47  logLoopTableAssoc(p->logLoopTableAssoc),
48  confidenceThreshold((1 << loopTableConfidenceBits) - 1),
49  loopTagMask((1 << loopTableTagBits) - 1),
50  loopNumIterMask((1 << loopTableIterBits) - 1),
51  loopSetMask((1 << (logSizeLoopPred - logLoopTableAssoc)) - 1),
52  loopUseCounter(-1),
53  withLoopBits(p->withLoopBits),
54  useDirectionBit(p->useDirectionBit),
55  useSpeculation(p->useSpeculation),
56  useHashing(p->useHashing),
57  restrictAllocation(p->restrictAllocation),
58  initialLoopIter(p->initialLoopIter),
59  initialLoopAge(p->initialLoopAge),
60  optionalAgeReset(p->optionalAgeReset),
61  stats(this)
62 {
63  assert(initialLoopAge <= ((1 << loopTableAgeBits) - 1));
64 }
65 
66 void
68 {
69  // we use uint16_t type for these vales, so they cannot be more than
70  // 16 bits
71  assert(loopTableTagBits <= 16);
72  assert(loopTableIterBits <= 16);
73 
75 
76  ltable = new LoopEntry[ULL(1) << logSizeLoopPred];
77 }
78 
81 {
82  return new BranchInfo();
83 }
84 
85 int
86 LoopPredictor::lindex(Addr pc_in, unsigned instShiftAmt) const
87 {
88  // The loop table is implemented as a linear table
89  // If associativity is N (N being 1 << logLoopTableAssoc),
90  // the first N entries are for set 0, the next N entries are for set 1,
91  // and so on.
92  // Thus, this function calculates the set and then it gets left shifted
93  // by logLoopTableAssoc in order to return the index of the first of the
94  // N entries of the set
95  Addr pc = pc_in >> instShiftAmt;
96  if (useHashing) {
97  pc ^= pc_in;
98  }
99  return ((pc & loopSetMask) << logLoopTableAssoc);
100 }
101 
102 int
103 LoopPredictor::finallindex(int index, int lowPcBits, int way) const
104 {
105  return (useHashing ? (index ^ ((lowPcBits >> way) << logLoopTableAssoc)) :
106  (index))
107  + way;
108 }
109 
110 //loop prediction: only used if high confidence
111 bool
113  unsigned instShiftAmt) const
114 {
115  bi->loopHit = -1;
116  bi->loopPredValid = false;
117  bi->loopIndex = lindex(pc, instShiftAmt);
118 
119  if (useHashing) {
120  unsigned pcShift = logSizeLoopPred - logLoopTableAssoc;
121  bi->loopIndexB = (pc >> pcShift) & loopSetMask;
122  bi->loopTag = (pc >> pcShift) ^ (pc >> (pcShift + loopTableTagBits));
123  bi->loopTag &= loopTagMask;
124  } else {
125  unsigned pcShift = instShiftAmt + logSizeLoopPred - logLoopTableAssoc;
126  bi->loopTag = (pc >> pcShift) & loopTagMask;
127  // bi->loopIndexB is not used without hash
128  }
129 
130  for (int i = 0; i < (1 << logLoopTableAssoc); i++) {
131  int idx = finallindex(bi->loopIndex, bi->loopIndexB, i);
132  if (ltable[idx].tag == bi->loopTag) {
133  bi->loopHit = i;
134  bi->loopPredValid = calcConf(idx);
135 
136  uint16_t iter = speculative ? ltable[idx].currentIterSpec
137  : ltable[idx].currentIter;
138 
139  if ((iter + 1) == ltable[idx].numIter) {
140  return useDirectionBit ? !(ltable[idx].dir) : false;
141  } else {
142  return useDirectionBit ? (ltable[idx].dir) : true;
143  }
144  }
145  }
146  return false;
147 }
148 
149 bool
151 {
153 }
154 
155 void
157 {
158  if (bi->loopHit>=0) {
159  int index = finallindex(bi->loopIndex, bi->loopIndexB, bi->loopHit);
160  if (taken != ltable[index].dir) {
162  } else {
165  }
166  }
167 }
168 
169 bool
171 {
172  return false;
173 }
174 
175 void
176 LoopPredictor::loopUpdate(Addr pc, bool taken, BranchInfo* bi, bool tage_pred)
177 {
178  int idx = finallindex(bi->loopIndex, bi->loopIndexB, bi->loopHit);
179  if (bi->loopHit >= 0) {
180  //already a hit
181  if (bi->loopPredValid) {
182  if (taken != bi->loopPred) {
183  // free the entry
184  ltable[idx].numIter = 0;
185  ltable[idx].age = 0;
186  ltable[idx].confidence = 0;
187  ltable[idx].currentIter = 0;
188  return;
189  } else if (bi->loopPred != tage_pred || optionalAgeInc()) {
190  DPRINTF(LTage, "Loop Prediction success:%lx\n",pc);
191  unsignedCtrUpdate(ltable[idx].age, true, loopTableAgeBits);
192  }
193  }
194 
195  ltable[idx].currentIter =
196  (ltable[idx].currentIter + 1) & loopNumIterMask;
197  if (ltable[idx].currentIter > ltable[idx].numIter) {
198  ltable[idx].confidence = 0;
199  if (ltable[idx].numIter != 0) {
200  // free the entry
201  ltable[idx].numIter = 0;
202  if (optionalAgeReset) {
203  ltable[idx].age = 0;
204  }
205  }
206  }
207 
208  if (taken != (useDirectionBit ? ltable[idx].dir : true)) {
209  if (ltable[idx].currentIter == ltable[idx].numIter) {
210  DPRINTF(LTage, "Loop End predicted successfully:%lx\n", pc);
211  unsignedCtrUpdate(ltable[idx].confidence, true,
213  //just do not predict when the loop count is 1 or 2
214  if (ltable[idx].numIter < 3) {
215  // free the entry
216  ltable[idx].dir = taken; // ignored if no useDirectionBit
217  ltable[idx].numIter = 0;
218  ltable[idx].age = 0;
219  ltable[idx].confidence = 0;
220  }
221  } else {
222  DPRINTF(LTage, "Loop End predicted incorrectly:%lx\n", pc);
223  if (ltable[idx].numIter == 0) {
224  // first complete nest;
225  ltable[idx].confidence = 0;
226  ltable[idx].numIter = ltable[idx].currentIter;
227  } else {
228  //not the same number of iterations as last time: free the
229  //entry
230  ltable[idx].numIter = 0;
231  if (optionalAgeReset) {
232  ltable[idx].age = 0;
233  }
234  ltable[idx].confidence = 0;
235  }
236  }
237  ltable[idx].currentIter = 0;
238  }
239 
240  } else if (useDirectionBit ? (bi->predTaken != taken) : taken) {
241  if ((random_mt.random<int>() & 3) == 0 || !restrictAllocation) {
242  //try to allocate an entry on taken branch
243  int nrand = random_mt.random<int>();
244  for (int i = 0; i < (1 << logLoopTableAssoc); i++) {
245  int loop_hit = (nrand + i) & ((1 << logLoopTableAssoc) - 1);
246  idx = finallindex(bi->loopIndex, bi->loopIndexB, loop_hit);
247  if (ltable[idx].age == 0) {
248  DPRINTF(LTage,
249  "Allocating loop pred entry for branch %lx\n",
250  pc);
251  ltable[idx].dir = !taken; // ignored if no useDirectionBit
252  ltable[idx].tag = bi->loopTag;
253  ltable[idx].numIter = 0;
254  ltable[idx].age = initialLoopAge;
255  ltable[idx].confidence = 0;
257  break;
258 
259  } else {
260  ltable[idx].age--;
261  }
262  if (restrictAllocation) {
263  break;
264  }
265  }
266  }
267  }
268 }
269 
270 bool
271 LoopPredictor::loopPredict(ThreadID tid, Addr branch_pc, bool cond_branch,
272  BranchInfo* bi, bool prev_pred_taken, unsigned instShiftAmt)
273 {
274  bool pred_taken = prev_pred_taken;
275  if (cond_branch) {
276  // loop prediction
277  bi->loopPred = getLoop(branch_pc, bi, useSpeculation, instShiftAmt);
278 
279  if ((loopUseCounter >= 0) && bi->loopPredValid) {
280  pred_taken = bi->loopPred;
281  bi->loopPredUsed = true;
282  }
283 
284  if (useSpeculation) {
285  specLoopUpdate(pred_taken, bi);
286  }
287  }
288 
289  return pred_taken;
290 }
291 
292 void
294 {
295  if (bi->loopHit >= 0) {
296  int idx = finallindex(bi->loopIndex,
297  bi->loopIndexB,
298  bi->loopHit);
299  ltable[idx].currentIterSpec = bi->currentIter;
300  }
301 }
302 
303 void
305 {
306  if (bi->loopHit >= 0) {
307  int idx = finallindex(bi->loopIndex,
308  bi->loopIndexB,
309  bi->loopHit);
310  ltable[idx].currentIterSpec = bi->currentIter;
311  }
312 }
313 
314 void
316 {
317  if (taken == bi->loopPred) {
318  stats.correct++;
319  } else {
320  stats.wrong++;
321  }
322 }
323 
324 void
325 LoopPredictor::condBranchUpdate(ThreadID tid, Addr branch_pc, bool taken,
326  bool tage_pred, BranchInfo* bi,
327  unsigned instShiftAmt)
328 {
329  if (useSpeculation) {
330  // recalculate loop prediction without speculation
331  // It is ok to overwrite the loop prediction fields in bi
332  // as the stats have already been updated with the previous
333  // values
334  bi->loopPred = getLoop(branch_pc, bi, false, instShiftAmt);
335  }
336 
337  if (bi->loopPredValid) {
338  if (bi->predTaken != bi->loopPred) {
340  (bi->loopPred == taken),
341  withLoopBits);
342  }
343  }
344 
345  loopUpdate(branch_pc, taken, bi, tage_pred);
346 }
347 
349  : Stats::Group(parent),
350  ADD_STAT(correct, "Number of times the loop predictor is"
351  " the provider and the prediction is correct"),
352  ADD_STAT(wrong, "Number of times the loop predictor is the"
353  " provider and the prediction is wrong")
354 {
355 }
356 
357 size_t
359 {
360  return (1ULL << logSizeLoopPred) *
361  ((useSpeculation ? 3 : 2) * loopTableIterBits +
364 }
365 
367 LoopPredictorParams::create()
368 {
369  return new LoopPredictor(this);
370 }
LoopPredictor::LoopEntry::tag
uint16_t tag
Definition: loop_predictor.hh:65
LoopPredictor::loopTableConfidenceBits
const unsigned loopTableConfidenceBits
Definition: loop_predictor.hh:48
LoopPredictor::unsignedCtrUpdate
static void unsignedCtrUpdate(uint8_t &ctr, bool up, unsigned nbits)
Updates an unsigned counter based on up/down parameter.
Definition: loop_predictor.hh:99
MipsISA::index
Bitfield< 30, 0 > index
Definition: pra_constants.hh:44
LoopPredictor::updateStats
void updateStats(bool taken, BranchInfo *bi)
Update the stats.
Definition: loop_predictor.cc:315
LoopPredictor::BranchInfo
Definition: loop_predictor.hh:122
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
ThreadID
int16_t ThreadID
Thread index/ID type.
Definition: types.hh:227
LoopPredictor::stats
LoopPredictor::LoopPredictorStats stats
LoopPredictor::withLoopBits
unsigned withLoopBits
Definition: loop_predictor.hh:76
random.hh
LoopPredictor::squash
void squash(ThreadID tid, BranchInfo *bi)
Definition: loop_predictor.cc:293
LoopPredictor::finallindex
int finallindex(int lindex, int lowPcBits, int way) const
Computes the index used to access the ltable structures.
Definition: loop_predictor.cc:103
LoopPredictor::confidenceThreshold
const uint8_t confidenceThreshold
Definition: loop_predictor.hh:52
LoopPredictor::specLoopUpdate
void specLoopUpdate(bool taken, BranchInfo *bi)
Speculatively updates the loop predictor iteration count (only for useSpeculation).
Definition: loop_predictor.cc:156
LoopPredictor
Definition: loop_predictor.hh:43
LoopPredictor::loopUpdate
void loopUpdate(Addr pc, bool Taken, BranchInfo *bi, bool tage_pred)
Updates the loop predictor.
Definition: loop_predictor.cc:176
LoopPredictor::loopSetMask
const int loopSetMask
Definition: loop_predictor.hh:55
LoopPredictor::loopUseCounter
int8_t loopUseCounter
Definition: loop_predictor.hh:75
LoopPredictor::initialLoopAge
const unsigned initialLoopAge
Definition: loop_predictor.hh:83
LoopPredictor::optionalAgeInc
virtual bool optionalAgeInc() const
Definition: loop_predictor.cc:170
LoopPredictor::LoopPredictorStats::correct
Stats::Scalar correct
Definition: loop_predictor.hh:88
LoopPredictor::optionalAgeReset
const bool optionalAgeReset
Definition: loop_predictor.hh:84
LoopPredictor::LoopPredictorStats::wrong
Stats::Scalar wrong
Definition: loop_predictor.hh:89
LoopPredictor::calcConf
virtual bool calcConf(int index) const
Definition: loop_predictor.cc:150
random_mt
Random random_mt
Definition: random.cc:96
PowerISA::bi
Bitfield< 20, 16 > bi
Definition: types.hh:63
LoopPredictor::makeBranchInfo
virtual BranchInfo * makeBranchInfo()
Definition: loop_predictor.cc:80
LoopPredictor::useHashing
const bool useHashing
Definition: loop_predictor.hh:80
LoopPredictor::useSpeculation
const bool useSpeculation
Definition: loop_predictor.hh:79
LoopPredictor::LoopPredictor
LoopPredictor(LoopPredictorParams *p)
Definition: loop_predictor.cc:41
LoopPredictor::init
void init() override
Initialize the loop predictor.
Definition: loop_predictor.cc:67
LoopPredictor::ltable
LoopEntry * ltable
Definition: loop_predictor.hh:73
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:234
ADD_STAT
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition: group.hh:67
LoopPredictor::loopTagMask
const uint16_t loopTagMask
Definition: loop_predictor.hh:53
MipsISA::pc
Bitfield< 4 > pc
Definition: pra_constants.hh:240
LoopPredictor::LoopPredictorStats::LoopPredictorStats
LoopPredictorStats(Stats::Group *parent)
Definition: loop_predictor.cc:348
LoopPredictor::logSizeLoopPred
const unsigned logSizeLoopPred
Definition: loop_predictor.hh:46
LoopPredictor::squashLoop
void squashLoop(BranchInfo *bi)
Definition: loop_predictor.cc:304
LoopPredictor::initialLoopIter
const unsigned initialLoopIter
Definition: loop_predictor.hh:82
LoopPredictor::loopTableIterBits
const unsigned loopTableIterBits
Definition: loop_predictor.hh:50
LoopPredictor::getLoop
bool getLoop(Addr pc, BranchInfo *bi, bool speculative, unsigned instShiftAmt) const
Get a branch prediction from the loop predictor.
Definition: loop_predictor.cc:112
LoopPredictor::signedCtrUpdate
static void signedCtrUpdate(int8_t &ctr, bool up, unsigned nbits)
Definition: loop_predictor.hh:110
LoopPredictor::LoopEntry::confidence
uint8_t confidence
Definition: loop_predictor.hh:64
LoopPredictor::LoopEntry
Definition: loop_predictor.hh:59
LoopPredictor::loopPredict
bool loopPredict(ThreadID tid, Addr branch_pc, bool cond_branch, BranchInfo *bi, bool prev_pred_taken, unsigned instShiftAmt)
Get the loop prediction.
Definition: loop_predictor.cc:271
Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
LoopPredictor::loopTableTagBits
const unsigned loopTableTagBits
Definition: loop_predictor.hh:49
LoopPredictor::LoopEntry::numIter
uint16_t numIter
Definition: loop_predictor.hh:61
LoopPredictor::restrictAllocation
const bool restrictAllocation
Definition: loop_predictor.hh:81
LoopPredictor::loopTableAgeBits
const unsigned loopTableAgeBits
Definition: loop_predictor.hh:47
LoopPredictor::LoopEntry::age
uint8_t age
Definition: loop_predictor.hh:66
LoopPredictor::getSizeInBits
size_t getSizeInBits() const
Definition: loop_predictor.cc:358
LoopPredictor::LoopEntry::dir
bool dir
Definition: loop_predictor.hh:67
LoopPredictor::LoopEntry::currentIterSpec
uint16_t currentIterSpec
Definition: loop_predictor.hh:63
loop_predictor.hh
Stats::Group
Statistics container.
Definition: group.hh:83
LoopPredictor::condBranchUpdate
void condBranchUpdate(ThreadID tid, Addr branch_pc, bool taken, bool tage_pred, BranchInfo *bi, unsigned instShiftAmt)
Update LTAGE for conditional branches.
Definition: loop_predictor.cc:325
Random::random
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:86
Stats
Definition: statistics.cc:61
trace.hh
LoopPredictor::lindex
int lindex(Addr pc_in, unsigned instShiftAmt) const
Computes the index used to access the loop predictor.
Definition: loop_predictor.cc:86
MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:323
LoopPredictor::logLoopTableAssoc
const unsigned logLoopTableAssoc
Definition: loop_predictor.hh:51
LoopPredictor::loopNumIterMask
const uint16_t loopNumIterMask
Definition: loop_predictor.hh:54
LoopPredictor::LoopEntry::currentIter
uint16_t currentIter
Definition: loop_predictor.hh:62
ULL
#define ULL(N)
uint64_t constant
Definition: types.hh:50
LoopPredictor::useDirectionBit
const bool useDirectionBit
Definition: loop_predictor.hh:78
SimObject
Abstract superclass for simulation objects.
Definition: sim_object.hh:92

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