gem5  v19.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
bi_mode.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 The Regents of The University of Michigan
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met: redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer;
9  * redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution;
12  * neither the name of the copyright holders nor the names of its
13  * contributors may be used to endorse or promote products derived from
14  * this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  * Authors: Anthony Gutierrez
29  */
30 
31 /* @file
32  * Implementation of a bi-mode branch predictor
33  */
34 
35 #include "cpu/pred/bi_mode.hh"
36 
37 #include "base/bitfield.hh"
38 #include "base/intmath.hh"
39 
40 BiModeBP::BiModeBP(const BiModeBPParams *params)
41  : BPredUnit(params),
42  globalHistoryReg(params->numThreads, 0),
43  globalHistoryBits(ceilLog2(params->globalPredictorSize)),
44  choicePredictorSize(params->choicePredictorSize),
45  choiceCtrBits(params->choiceCtrBits),
46  globalPredictorSize(params->globalPredictorSize),
47  globalCtrBits(params->globalCtrBits),
48  choiceCounters(choicePredictorSize, SatCounter(choiceCtrBits)),
49  takenCounters(globalPredictorSize, SatCounter(globalCtrBits)),
50  notTakenCounters(globalPredictorSize, SatCounter(globalCtrBits))
51 {
53  fatal("Invalid choice predictor size.\n");
55  fatal("Invalid global history predictor size.\n");
56 
60 
61  choiceThreshold = (ULL(1) << (choiceCtrBits - 1)) - 1;
62  takenThreshold = (ULL(1) << (globalCtrBits - 1)) - 1;
63  notTakenThreshold = (ULL(1) << (globalCtrBits - 1)) - 1;
64 }
65 
66 /*
67  * For an unconditional branch we set its history such that
68  * everything is set to taken. I.e., its choice predictor
69  * chooses the taken array and the taken array predicts taken.
70  */
71 void
72 BiModeBP::uncondBranch(ThreadID tid, Addr pc, void * &bpHistory)
73 {
74  BPHistory *history = new BPHistory;
75  history->globalHistoryReg = globalHistoryReg[tid];
76  history->takenUsed = true;
77  history->takenPred = true;
78  history->notTakenPred = true;
79  history->finalPred = true;
80  bpHistory = static_cast<void*>(history);
81  updateGlobalHistReg(tid, true);
82 }
83 
84 void
85 BiModeBP::squash(ThreadID tid, void *bpHistory)
86 {
87  BPHistory *history = static_cast<BPHistory*>(bpHistory);
88  globalHistoryReg[tid] = history->globalHistoryReg;
89 
90  delete history;
91 }
92 
93 /*
94  * Here we lookup the actual branch prediction. We use the PC to
95  * identify the bias of a particular branch, which is based on the
96  * prediction in the choice array. A hash of the global history
97  * register and a branch's PC is used to index into both the taken
98  * and not-taken predictors, which both present a prediction. The
99  * choice array's prediction is used to select between the two
100  * direction predictors for the final branch prediction.
101  */
102 bool
103 BiModeBP::lookup(ThreadID tid, Addr branchAddr, void * &bpHistory)
104 {
105  unsigned choiceHistoryIdx = ((branchAddr >> instShiftAmt)
107  unsigned globalHistoryIdx = (((branchAddr >> instShiftAmt)
108  ^ globalHistoryReg[tid])
110 
111  assert(choiceHistoryIdx < choicePredictorSize);
112  assert(globalHistoryIdx < globalPredictorSize);
113 
114  bool choicePrediction = choiceCounters[choiceHistoryIdx]
115  > choiceThreshold;
116  bool takenGHBPrediction = takenCounters[globalHistoryIdx]
117  > takenThreshold;
118  bool notTakenGHBPrediction = notTakenCounters[globalHistoryIdx]
120  bool finalPrediction;
121 
122  BPHistory *history = new BPHistory;
123  history->globalHistoryReg = globalHistoryReg[tid];
124  history->takenUsed = choicePrediction;
125  history->takenPred = takenGHBPrediction;
126  history->notTakenPred = notTakenGHBPrediction;
127 
128  if (choicePrediction) {
129  finalPrediction = takenGHBPrediction;
130  } else {
131  finalPrediction = notTakenGHBPrediction;
132  }
133 
134  history->finalPred = finalPrediction;
135  bpHistory = static_cast<void*>(history);
136  updateGlobalHistReg(tid, finalPrediction);
137 
138  return finalPrediction;
139 }
140 
141 void
142 BiModeBP::btbUpdate(ThreadID tid, Addr branchAddr, void * &bpHistory)
143 {
144  globalHistoryReg[tid] &= (historyRegisterMask & ~ULL(1));
145 }
146 
147 /* Only the selected direction predictor will be updated with the final
148  * outcome; the status of the unselected one will not be altered. The choice
149  * predictor is always updated with the branch outcome, except when the
150  * choice is opposite to the branch outcome but the selected counter of
151  * the direction predictors makes a correct final prediction.
152  */
153 void
154 BiModeBP::update(ThreadID tid, Addr branchAddr, bool taken, void *bpHistory,
155  bool squashed, const StaticInstPtr & inst, Addr corrTarget)
156 {
157  assert(bpHistory);
158 
159  BPHistory *history = static_cast<BPHistory*>(bpHistory);
160 
161  // We do not update the counters speculatively on a squash.
162  // We just restore the global history register.
163  if (squashed) {
164  globalHistoryReg[tid] = (history->globalHistoryReg << 1) | taken;
165  return;
166  }
167 
168  unsigned choiceHistoryIdx = ((branchAddr >> instShiftAmt)
170  unsigned globalHistoryIdx = (((branchAddr >> instShiftAmt)
171  ^ history->globalHistoryReg)
173 
174  assert(choiceHistoryIdx < choicePredictorSize);
175  assert(globalHistoryIdx < globalPredictorSize);
176 
177  if (history->takenUsed) {
178  // if the taken array's prediction was used, update it
179  if (taken) {
180  takenCounters[globalHistoryIdx]++;
181  } else {
182  takenCounters[globalHistoryIdx]--;
183  }
184  } else {
185  // if the not-taken array's prediction was used, update it
186  if (taken) {
187  notTakenCounters[globalHistoryIdx]++;
188  } else {
189  notTakenCounters[globalHistoryIdx]--;
190  }
191  }
192 
193  if (history->finalPred == taken) {
194  /* If the final prediction matches the actual branch's
195  * outcome and the choice predictor matches the final
196  * outcome, we update the choice predictor, otherwise it
197  * is not updated. While the designers of the bi-mode
198  * predictor don't explicity say why this is done, one
199  * can infer that it is to preserve the choice predictor's
200  * bias with respect to the branch being predicted; afterall,
201  * the whole point of the bi-mode predictor is to identify the
202  * atypical case when a branch deviates from its bias.
203  */
204  if (history->finalPred == history->takenUsed) {
205  if (taken) {
206  choiceCounters[choiceHistoryIdx]++;
207  } else {
208  choiceCounters[choiceHistoryIdx]--;
209  }
210  }
211  } else {
212  // always update the choice predictor on an incorrect prediction
213  if (taken) {
214  choiceCounters[choiceHistoryIdx]++;
215  } else {
216  choiceCounters[choiceHistoryIdx]--;
217  }
218  }
219 
220  delete history;
221 }
222 
223 void
225 {
226  globalHistoryReg[tid] = taken ? (globalHistoryReg[tid] << 1) | 1 :
227  (globalHistoryReg[tid] << 1);
229 }
230 
231 BiModeBP*
232 BiModeBPParams::create()
233 {
234  return new BiModeBP(this);
235 }
unsigned globalHistoryBits
Definition: bi_mode.hh:91
void squash(ThreadID tid, void *bp_history)
Definition: bi_mode.cc:85
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:175
void btbUpdate(ThreadID tid, Addr branch_addr, void *&bp_history)
If a branch is not taken, because the BTB address is invalid or missing, this function sets the appro...
Definition: bi_mode.cc:142
unsigned choiceCtrBits
Definition: bi_mode.hh:95
bool lookup(ThreadID tid, Addr branch_addr, void *&bp_history)
Looks up a given PC in the BP to see if it is taken or not taken.
Definition: bi_mode.cc:103
void updateGlobalHistReg(ThreadID tid, bool taken)
Definition: bi_mode.cc:224
std::vector< SatCounter > choiceCounters
Definition: bi_mode.hh:102
unsigned globalPredictorSize
Definition: bi_mode.hh:97
std::vector< unsigned > globalHistoryReg
Definition: bi_mode.hh:90
int ceilLog2(const T &n)
Definition: intmath.hh:135
unsigned globalCtrBits
Definition: bi_mode.hh:98
unsigned choiceThreshold
Definition: bi_mode.hh:108
unsigned globalHistoryReg
Definition: bi_mode.hh:71
unsigned choiceHistoryMask
Definition: bi_mode.hh:96
unsigned historyRegisterMask
Definition: bi_mode.hh:92
Bitfield< 4 > pc
Implements an n bit saturating counter and provides methods to increment, decrement, and read it.
Definition: sat_counter.hh:57
bool isPowerOf2(const T &n)
Definition: intmath.hh:146
unsigned choicePredictorSize
Definition: bi_mode.hh:94
std::vector< SatCounter > notTakenCounters
Definition: bi_mode.hh:106
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
#define ULL(N)
uint64_t constant
Definition: types.hh:50
Basically a wrapper class to hold both the branch predictor and the BTB.
Definition: bpred_unit.hh:67
int16_t ThreadID
Thread index/ID type.
Definition: types.hh:227
unsigned takenThreshold
Definition: bi_mode.hh:109
std::vector< SatCounter > takenCounters
Definition: bi_mode.hh:104
unsigned globalHistoryMask
Definition: bi_mode.hh:99
const unsigned instShiftAmt
Number of bits to shift instructions by for predictor addresses.
Definition: bpred_unit.hh:321
Bitfield< 3, 0 > mask
Definition: types.hh:64
BiModeBP(const BiModeBPParams *params)
Definition: bi_mode.cc:40
void update(ThreadID tid, Addr branch_addr, bool taken, void *bp_history, bool squashed, const StaticInstPtr &inst, Addr corrTarget)
Updates the BP with taken/not taken information.
Definition: bi_mode.cc:154
Implements a bi-mode branch predictor.
Definition: bi_mode.hh:56
void uncondBranch(ThreadID tid, Addr pc, void *&bp_history)
Definition: bi_mode.cc:72
unsigned notTakenThreshold
Definition: bi_mode.hh:110

Generated on Fri Feb 28 2020 16:26:59 for gem5 by doxygen 1.8.13