gem5 [DEVELOP-FOR-25.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)
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
198TournamentBP::updateHistories(ThreadID tid, Addr pc, bool uncond, bool taken,
199 Addr target, const StaticInstPtr &inst,
200 void * &bp_history)
201{
202 assert(uncond || bp_history);
203 if (uncond) {
204 // Create BPHistory and pass it back to be recorded.
205 BPHistory *history = new BPHistory;
206 history->globalHistory = globalHistory[tid];
207 history->localPredTaken = true;
208 history->globalPredTaken = true;
209 history->globalUsed = true;
212 bp_history = static_cast<void *>(history);
213 }
214
215 // Update the global history for all branches
216 updateGlobalHist(tid, taken);
217
218 // Update the local history only for conditional branches
219 if (!uncond) {
220 auto history = static_cast<BPHistory *>(bp_history);
221 updateLocalHist(history->localHistoryIdx, taken);
222 }
223}
224
225
226void
228 void * &bp_history, bool squashed,
229 const StaticInstPtr & inst, Addr target)
230{
231 assert(bp_history);
232
233 BPHistory *history = static_cast<BPHistory *>(bp_history);
234
235 unsigned local_history_idx = calcLocHistIdx(pc);
236
237 assert(local_history_idx < localHistoryTableSize);
238
239 // Unconditional branches do not use local history.
240 bool old_local_pred_valid = history->localHistory !=
242
243 // If this is a misprediction, restore the speculatively
244 // updated state (global history register and local history)
245 // and update again.
246 if (squashed) {
247 // Global history restore and update
248 globalHistory[tid] = (history->globalHistory << 1) | taken;
250
251 // Local history restore and update.
252 if (old_local_pred_valid) {
253 localHistoryTable[local_history_idx] =
254 (history->localHistory << 1) | taken;
255 }
256
257 return;
258 }
259
260 unsigned old_local_pred_index = history->localHistory &
262
263 assert(old_local_pred_index < localPredictorSize);
264
265 // Update the choice predictor to tell it which one was correct if
266 // there was a prediction.
267 if (history->localPredTaken != history->globalPredTaken &&
268 old_local_pred_valid)
269 {
270 // If the local prediction matches the actual outcome,
271 // decrement the counter. Otherwise increment the
272 // counter.
273 unsigned choice_predictor_idx =
275 if (history->localPredTaken == taken) {
276 choiceCtrs[choice_predictor_idx]--;
277 } else if (history->globalPredTaken == taken) {
278 choiceCtrs[choice_predictor_idx]++;
279 }
280 }
281
282 // Update the counters with the proper
283 // resolution of the branch. Histories are updated
284 // speculatively, restored upon squash() calls, and
285 // recomputed upon update(squash = true) calls,
286 // so they do not need to be updated.
287 unsigned global_predictor_idx =
289 if (taken) {
290 globalCtrs[global_predictor_idx]++;
291 if (old_local_pred_valid) {
292 localCtrs[old_local_pred_index]++;
293 }
294 } else {
295 globalCtrs[global_predictor_idx]--;
296 if (old_local_pred_valid) {
297 localCtrs[old_local_pred_index]--;
298 }
299 }
300
301 // We're done with this history, now delete it.
302 delete history;
303 bp_history = nullptr;
304}
305
306void
307TournamentBP::squash(ThreadID tid, void * &bp_history)
308{
309 BPHistory *history = static_cast<BPHistory *>(bp_history);
310
311 // Restore global history to state prior to this branch.
312 globalHistory[tid] = history->globalHistory;
313
314 // Restore local history
315 if (history->localHistoryIdx != invalidPredictorIndex) {
317 }
318
319 // Delete this BPHistory now that we're done with it.
320 delete history;
321 bp_history = nullptr;
322}
323
324#ifdef GEM5_DEBUG
325int
326TournamentBP::BPHistory::newCount = 0;
327#endif
328
329} // namespace branch_prediction
330} // namespace gem5
BPredUnit(const Params &p)
Branch Predictor Unit (BPU) interface functions.
Definition bpred_unit.cc:58
const unsigned numThreads
Number of the threads for which the branch history is maintained.
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.
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.
void updateHistories(ThreadID tid, Addr pc, bool uncond, bool taken, Addr target, const StaticInstPtr &inst, void *&bp_history) override
Ones done with the prediction this function updates the path and global history.
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:232
GenericSatCounter< uint8_t > SatCounter8
const Params & params() const
#define inform(...)
Definition logging.hh:289
Bitfield< 3, 0 > mask
Definition pcstate.hh:63
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 4 > pc
Copyright (c) 2024 Arm Limited 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
RefCountingPtr< StaticInst > StaticInstPtr
The branch history information that is created upon predicting a branch.

Generated on Mon May 26 2025 09:19:08 for gem5 by doxygen 1.13.2