gem5 v24.0.0.0
Loading...
Searching...
No Matches
tournament.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2011, 2014 ARM Limited
3 * Copyright (c) 2022-2023 The University of Edinburgh
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) 2004-2006 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
43
44#include "base/bitfield.hh"
45#include "base/intmath.hh"
46
47namespace gem5
48{
49
50namespace branch_prediction
51{
52
53TournamentBP::TournamentBP(const TournamentBPParams &params)
54 : BPredUnit(params),
55 localPredictorSize(params.localPredictorSize),
56 localCtrBits(params.localCtrBits),
57 localCtrs(localPredictorSize, SatCounter8(localCtrBits)),
58 localHistoryTableSize(params.localHistoryTableSize),
59 localHistoryBits(ceilLog2(params.localPredictorSize)),
60 globalPredictorSize(params.globalPredictorSize),
61 globalCtrBits(params.globalCtrBits),
62 globalCtrs(globalPredictorSize, SatCounter8(globalCtrBits)),
63 globalHistory(params.numThreads, 0),
64 globalHistoryBits(
65 ceilLog2(params.globalPredictorSize) >
66 ceilLog2(params.choicePredictorSize) ?
67 ceilLog2(params.globalPredictorSize) :
68 ceilLog2(params.choicePredictorSize)),
69 choicePredictorSize(params.choicePredictorSize),
70 choiceCtrBits(params.choiceCtrBits),
71 choiceCtrs(choicePredictorSize, SatCounter8(choiceCtrBits))
72{
74 fatal("Invalid local predictor size!\n");
75 }
76
78 fatal("Invalid global predictor size!\n");
79 }
80
82
84 fatal("Invalid local history table size!\n");
85 }
86
87 //Setup the history table for the local table
89
90 for (int i = 0; i < localHistoryTableSize; ++i)
92
93 // Set up the global history mask
94 // this is equivalent to mask(log2(globalPredictorSize)
96
98 fatal("Invalid choice predictor size!\n");
99 }
100
101 // Set up choiceHistoryMask
102 // this is equivalent to mask(log2(choicePredictorSize)
104
105 //Set up historyRegisterMask
107
108 //Check that predictors don't use more bits than they have available
110 fatal("Global predictor too large for global history bits!\n");
111 }
113 fatal("Choice predictor too large for global history bits!\n");
114 }
115
118 inform("More global history bits than required by predictors\n");
119 }
120
121 // Set thresholds for the three predictors' counters
122 // This is equivalent to (2^(Ctr))/2 - 1
123 localThreshold = (1ULL << (localCtrBits - 1)) - 1;
124 globalThreshold = (1ULL << (globalCtrBits - 1)) - 1;
125 choiceThreshold = (1ULL << (choiceCtrBits - 1)) - 1;
126}
127
128inline
129unsigned
131{
132 // Get low order bits after removing instruction offset.
133 return (branch_addr >> instShiftAmt) & (localHistoryTableSize - 1);
134}
135
136inline
137void
139{
140 globalHistory[tid] = (globalHistory[tid] << 1) | taken;
142}
143
144inline
145void
146TournamentBP::updateLocalHist(unsigned local_history_idx, bool taken)
147{
148 localHistoryTable[local_history_idx] =
149 (localHistoryTable[local_history_idx] << 1) | taken;
150}
151
152bool
153TournamentBP::lookup(ThreadID tid, Addr pc, void * &bp_history)
154{
155 bool local_prediction;
156 unsigned local_history_idx;
157 unsigned local_predictor_idx;
158
159 bool global_prediction;
160 bool choice_prediction;
161
162 //Lookup in the local predictor to get its branch prediction
163 local_history_idx = calcLocHistIdx(pc);
164 local_predictor_idx = localHistoryTable[local_history_idx]
166 local_prediction = localCtrs[local_predictor_idx] > localThreshold;
167
168 //Lookup in the global predictor to get its branch prediction
169 global_prediction = globalThreshold <
171
172 //Lookup in the choice predictor to see which one to use
173 choice_prediction = choiceThreshold <
175
176 // Create BPHistory and pass it back to be recorded.
177 BPHistory *history = new BPHistory;
178 history->globalHistory = globalHistory[tid];
179 history->localPredTaken = local_prediction;
180 history->globalPredTaken = global_prediction;
181 history->globalUsed = choice_prediction;
182 history->localHistoryIdx = local_history_idx;
183 history->localHistory = local_predictor_idx;
184 bp_history = (void *)history;
185
186 assert(local_history_idx < localHistoryTableSize);
187
188 // Select and return the prediction
189 // History update will be happen in the next function
190 if (choice_prediction) {
191 return global_prediction;
192 } else {
193 return local_prediction;
194 }
195}
196
197void
199 bool taken, Addr target, void * &bp_history)
200{
201 assert(uncond || bp_history);
202 if (uncond) {
203 // Create BPHistory and pass it back to be recorded.
204 BPHistory *history = new BPHistory;
205 history->globalHistory = globalHistory[tid];
206 history->localPredTaken = true;
207 history->globalPredTaken = true;
208 history->globalUsed = true;
211 bp_history = static_cast<void *>(history);
212 }
213
214 // Update the global history for all branches
215 updateGlobalHist(tid, taken);
216
217 // Update the local history only for conditional branches
218 if (!uncond) {
219 auto history = static_cast<BPHistory *>(bp_history);
220 updateLocalHist(history->localHistoryIdx, taken);
221 }
222}
223
224
225void
227 void * &bp_history, bool squashed,
228 const StaticInstPtr & inst, Addr target)
229{
230 assert(bp_history);
231
232 BPHistory *history = static_cast<BPHistory *>(bp_history);
233
234 unsigned local_history_idx = calcLocHistIdx(pc);
235
236 assert(local_history_idx < localHistoryTableSize);
237
238 // Unconditional branches do not use local history.
239 bool old_local_pred_valid = history->localHistory !=
241
242 // If this is a misprediction, restore the speculatively
243 // updated state (global history register and local history)
244 // and update again.
245 if (squashed) {
246 // Global history restore and update
247 globalHistory[tid] = (history->globalHistory << 1) | taken;
249
250 // Local history restore and update.
251 if (old_local_pred_valid) {
252 localHistoryTable[local_history_idx] =
253 (history->localHistory << 1) | taken;
254 }
255
256 return;
257 }
258
259 unsigned old_local_pred_index = history->localHistory &
261
262 assert(old_local_pred_index < localPredictorSize);
263
264 // Update the choice predictor to tell it which one was correct if
265 // there was a prediction.
266 if (history->localPredTaken != history->globalPredTaken &&
267 old_local_pred_valid)
268 {
269 // If the local prediction matches the actual outcome,
270 // decrement the counter. Otherwise increment the
271 // counter.
272 unsigned choice_predictor_idx =
274 if (history->localPredTaken == taken) {
275 choiceCtrs[choice_predictor_idx]--;
276 } else if (history->globalPredTaken == taken) {
277 choiceCtrs[choice_predictor_idx]++;
278 }
279 }
280
281 // Update the counters with the proper
282 // resolution of the branch. Histories are updated
283 // speculatively, restored upon squash() calls, and
284 // recomputed upon update(squash = true) calls,
285 // so they do not need to be updated.
286 unsigned global_predictor_idx =
288 if (taken) {
289 globalCtrs[global_predictor_idx]++;
290 if (old_local_pred_valid) {
291 localCtrs[old_local_pred_index]++;
292 }
293 } else {
294 globalCtrs[global_predictor_idx]--;
295 if (old_local_pred_valid) {
296 localCtrs[old_local_pred_index]--;
297 }
298 }
299
300 // We're done with this history, now delete it.
301 delete history;
302 bp_history = nullptr;
303}
304
305void
306TournamentBP::squash(ThreadID tid, void * &bp_history)
307{
308 BPHistory *history = static_cast<BPHistory *>(bp_history);
309
310 // Restore global history to state prior to this branch.
311 globalHistory[tid] = history->globalHistory;
312
313 // Restore local history
314 if (history->localHistoryIdx != invalidPredictorIndex) {
316 }
317
318 // Delete this BPHistory now that we're done with it.
319 delete history;
320 bp_history = nullptr;
321}
322
323#ifdef GEM5_DEBUG
324int
325TournamentBP::BPHistory::newCount = 0;
326#endif
327
328} // namespace branch_prediction
329} // 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.
unsigned globalHistoryMask
Mask to apply to globalHistory to access global history table.
std::vector< SatCounter8 > choiceCtrs
Array of counters that make up the choice predictor.
unsigned globalHistoryBits
Number of bits for the global history.
void updateGlobalHist(ThreadID tid, bool taken)
Updates global history with the given direction.
TournamentBP(const TournamentBPParams &params)
Default branch predictor constructor.
Definition tournament.cc:53
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.
unsigned globalPredictorSize
Number of entries in the global predictor.
std::vector< SatCounter8 > localCtrs
Local counters.
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.
unsigned localPredictorMask
Mask to truncate values stored in the local history table.
void squash(ThreadID tid, void *&bp_history) override
unsigned historyRegisterMask
Mask to control how much history is stored.
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.
static const int invalidPredictorIndex
Flag for invalid predictor index.
unsigned localHistoryBits
Number of bits for each entry of the local history table.
std::vector< unsigned > localHistoryTable
Array of local history table entries.
unsigned localCtrBits
Number of bits of the local predictor's counters.
unsigned localThreshold
Thresholds for the counter value; above the threshold is taken, equal to or below the threshold is no...
unsigned choiceHistoryMask
Mask to apply to globalHistory to access choice history table.
void updateLocalHist(unsigned local_history_idx, bool taken)
Updates local histories.
std::vector< SatCounter8 > globalCtrs
Array of counters that make up the global predictor.
unsigned localPredictorSize
Number of counters in the local predictor.
unsigned calcLocHistIdx(Addr &branch_addr)
Returns the local history index, given a branch address.
std::vector< unsigned > globalHistory
Global history register.
unsigned globalCtrBits
Number of bits of the global predictor's counters.
unsigned choiceCtrBits
Number of bits in the choice predictor's counters.
unsigned localHistoryTableSize
Number of entries in the local history table.
unsigned choicePredictorSize
Number of entries in the choice predictor.
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
#define inform(...)
Definition logging.hh:257
Bitfield< 3, 0 > mask
Definition pcstate.hh:63
Bitfield< 7 > i
Definition misc_types.hh:67
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
The branch history information that is created upon predicting a branch.

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