gem5 v24.0.0.0
Loading...
Searching...
No Matches
bi_mode.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2022-2023 The University of Edinburgh
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) 2014 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
41/* @file
42 * Implementation of a bi-mode branch predictor
43 */
44
45#include "cpu/pred/bi_mode.hh"
46
47#include "base/bitfield.hh"
48#include "base/intmath.hh"
49
50namespace gem5
51{
52
53namespace branch_prediction
54{
55
56BiModeBP::BiModeBP(const BiModeBPParams &params)
57 : BPredUnit(params),
58 globalHistoryReg(params.numThreads, 0),
59 globalHistoryBits(ceilLog2(params.globalPredictorSize)),
60 choicePredictorSize(params.choicePredictorSize),
61 choiceCtrBits(params.choiceCtrBits),
62 globalPredictorSize(params.globalPredictorSize),
63 globalCtrBits(params.globalCtrBits),
64 choiceCounters(choicePredictorSize, SatCounter8(choiceCtrBits)),
65 takenCounters(globalPredictorSize, SatCounter8(globalCtrBits)),
66 notTakenCounters(globalPredictorSize, SatCounter8(globalCtrBits))
67{
69 fatal("Invalid choice predictor size.\n");
71 fatal("Invalid global history predictor size.\n");
72
76
77 choiceThreshold = (1ULL << (choiceCtrBits - 1)) - 1;
78 takenThreshold = (1ULL << (globalCtrBits - 1)) - 1;
79 notTakenThreshold = (1ULL << (globalCtrBits - 1)) - 1;
80}
81
82/*
83 * For an unconditional branch we set its history such that
84 * everything is set to taken. I.e., its choice predictor
85 * chooses the taken array and the taken array predicts taken.
86 */
87void
88BiModeBP::uncondBranch(ThreadID tid, Addr pc, void * &bp_history)
89{
90 BPHistory *history = new BPHistory;
91 history->globalHistoryReg = globalHistoryReg[tid];
92 history->takenUsed = true;
93 history->takenPred = true;
94 history->notTakenPred = true;
95 history->finalPred = true;
96 bp_history = static_cast<void*>(history);
97}
98
99void
101 bool taken, Addr target, void * &bp_history)
102{
103 assert(uncond || bp_history);
104 if (uncond) {
105 uncondBranch(tid, pc, bp_history);
106 }
107 updateGlobalHistReg(tid, taken);
108}
109
110
111void
112BiModeBP::squash(ThreadID tid, void * &bp_history)
113{
114 BPHistory *history = static_cast<BPHistory*>(bp_history);
115 globalHistoryReg[tid] = history->globalHistoryReg;
116
117 delete history;
118 bp_history = nullptr;
119}
120
121/*
122 * Here we lookup the actual branch prediction. We use the PC to
123 * identify the bias of a particular branch, which is based on the
124 * prediction in the choice array. A hash of the global history
125 * register and a branch's PC is used to index into both the taken
126 * and not-taken predictors, which both present a prediction. The
127 * choice array's prediction is used to select between the two
128 * direction predictors for the final branch prediction.
129 */
130bool
131BiModeBP::lookup(ThreadID tid, Addr branchAddr, void * &bp_history)
132{
133 unsigned choiceHistoryIdx = ((branchAddr >> instShiftAmt)
135 unsigned globalHistoryIdx = (((branchAddr >> instShiftAmt)
136 ^ globalHistoryReg[tid])
138
139 assert(choiceHistoryIdx < choicePredictorSize);
140 assert(globalHistoryIdx < globalPredictorSize);
141
142 bool choicePrediction = choiceCounters[choiceHistoryIdx]
144 bool takenGHBPrediction = takenCounters[globalHistoryIdx]
146 bool notTakenGHBPrediction = notTakenCounters[globalHistoryIdx]
148 bool finalPrediction;
149
150 BPHistory *history = new BPHistory;
151 history->globalHistoryReg = globalHistoryReg[tid];
152 history->takenUsed = choicePrediction;
153 history->takenPred = takenGHBPrediction;
154 history->notTakenPred = notTakenGHBPrediction;
155
156 if (choicePrediction) {
157 finalPrediction = takenGHBPrediction;
158 } else {
159 finalPrediction = notTakenGHBPrediction;
160 }
161
162 history->finalPred = finalPrediction;
163 bp_history = static_cast<void*>(history);
164
165 return finalPrediction;
166}
167
168
169/* Only the selected direction predictor will be updated with the final
170 * outcome; the status of the unselected one will not be altered. The choice
171 * predictor is always updated with the branch outcome, except when the
172 * choice is opposite to the branch outcome but the selected counter of
173 * the direction predictors makes a correct final prediction.
174 */
175void
176BiModeBP::update(ThreadID tid, Addr branchAddr, bool taken,void * &bp_history,
177 bool squashed, const StaticInstPtr & inst, Addr target)
178{
179 assert(bp_history);
180
181 BPHistory *history = static_cast<BPHistory*>(bp_history);
182
183 // We do not update the counters speculatively on a squash.
184 // We just restore the global history register.
185 if (squashed) {
186 globalHistoryReg[tid] = (history->globalHistoryReg << 1) | taken;
187 return;
188 }
189
190 unsigned choiceHistoryIdx = ((branchAddr >> instShiftAmt)
192 unsigned globalHistoryIdx = (((branchAddr >> instShiftAmt)
193 ^ history->globalHistoryReg)
195
196 assert(choiceHistoryIdx < choicePredictorSize);
197 assert(globalHistoryIdx < globalPredictorSize);
198
199 if (history->takenUsed) {
200 // if the taken array's prediction was used, update it
201 if (taken) {
202 takenCounters[globalHistoryIdx]++;
203 } else {
204 takenCounters[globalHistoryIdx]--;
205 }
206 } else {
207 // if the not-taken array's prediction was used, update it
208 if (taken) {
209 notTakenCounters[globalHistoryIdx]++;
210 } else {
211 notTakenCounters[globalHistoryIdx]--;
212 }
213 }
214
215 if (history->finalPred == taken) {
216 /* If the final prediction matches the actual branch's
217 * outcome and the choice predictor matches the final
218 * outcome, we update the choice predictor, otherwise it
219 * is not updated. While the designers of the bi-mode
220 * predictor don't explicity say why this is done, one
221 * can infer that it is to preserve the choice predictor's
222 * bias with respect to the branch being predicted; afterall,
223 * the whole point of the bi-mode predictor is to identify the
224 * atypical case when a branch deviates from its bias.
225 */
226 if (history->finalPred == history->takenUsed) {
227 if (taken) {
228 choiceCounters[choiceHistoryIdx]++;
229 } else {
230 choiceCounters[choiceHistoryIdx]--;
231 }
232 }
233 } else {
234 // always update the choice predictor on an incorrect prediction
235 if (taken) {
236 choiceCounters[choiceHistoryIdx]++;
237 } else {
238 choiceCounters[choiceHistoryIdx]--;
239 }
240 }
241
242 delete history;
243 bp_history = nullptr;
244}
245
246void
248{
249 globalHistoryReg[tid] = taken ? (globalHistoryReg[tid] << 1) | 1 :
250 (globalHistoryReg[tid] << 1);
252}
253
254} // namespace branch_prediction
255} // namespace gem5
Basically a wrapper class to hold both the branch predictor and the BTB.
Definition bpred_unit.hh:71
const unsigned instShiftAmt
Number of bits to shift instructions by for predictor addresses.
void updateHistories(ThreadID tid, Addr pc, bool uncond, bool taken, Addr target, void *&bp_history) override
Ones done with the prediction this function updates the path and global history.
Definition bi_mode.cc:100
std::vector< unsigned > globalHistoryReg
Definition bi_mode.hh:109
std::vector< SatCounter8 > notTakenCounters
Definition bi_mode.hh:125
void updateGlobalHistReg(ThreadID tid, bool taken)
Definition bi_mode.cc:247
void uncondBranch(ThreadID tid, Addr pc, void *&bp_history)
Definition bi_mode.cc:88
void squash(ThreadID tid, void *&bp_history) override
Definition bi_mode.cc:112
std::vector< SatCounter8 > takenCounters
Definition bi_mode.hh:123
void update(ThreadID tid, Addr pc, bool taken, void *&bp_history, bool squashed, const StaticInstPtr &inst, Addr target) override
Updates the BP with taken/not taken information.
Definition bi_mode.cc:176
std::vector< SatCounter8 > choiceCounters
Definition bi_mode.hh:121
bool lookup(ThreadID tid, Addr pc, void *&bp_history) override
Looks up a given conditional branch PC of in the BP to see if it is taken or not taken.
Definition bi_mode.cc:131
BiModeBP(const BiModeBPParams &params)
Definition bi_mode.cc:56
static constexpr int ceilLog2(const T &n)
Definition intmath.hh:84
static constexpr bool isPowerOf2(const T &n)
Definition intmath.hh:98
#define fatal(...)
This implements a cprintf based fatal() function.
Definition logging.hh:200
Bitfield< 3, 0 > mask
Definition pcstate.hh:63
Bitfield< 4 > pc
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
int16_t ThreadID
Thread index/ID type.
Definition types.hh:235
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition types.hh:147

Generated on Tue Jun 18 2024 16:24:02 for gem5 by doxygen 1.11.0