gem5 v24.1.0.1
Loading...
Searching...
No Matches
tage_sc_l.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) 2018 Metempsy Technology Consulting
15 * All rights reserved.
16 *
17 * Copyright (c) 2006 INRIA (Institut National de Recherche en
18 * Informatique et en Automatique / French National Research Institute
19 * for Computer Science and Applied Mathematics)
20 *
21 * All rights reserved.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions are
25 * met: redistributions of source code must retain the above copyright
26 * notice, this list of conditions and the following disclaimer;
27 * redistributions in binary form must reproduce the above copyright
28 * notice, this list of conditions and the following disclaimer in the
29 * documentation and/or other materials provided with the distribution;
30 * neither the name of the copyright holders nor the names of its
31 * contributors may be used to endorse or promote products derived from
32 * this software without specific prior written permission.
33 *
34 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
35 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
36 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
37 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
38 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
39 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
40 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
41 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
42 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
43 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
44 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45 *
46 * Author: André Seznec, Pau Cabre, Javier Bueno
47 *
48 */
49
50/*
51 * TAGE-SC-L branch predictor base class (devised by Andre Seznec)
52 * It consits of a TAGE + a statistical corrector (SC) + a loop predictor (L)
53 */
54
55#include "cpu/pred/tage_sc_l.hh"
56
57#include "debug/TageSCL.hh"
58
59namespace gem5
60{
61
62namespace branch_prediction
63{
64
65bool
71
72bool
74{
75 return (rng->random<int>() & 7) == 0;
76}
77
78TAGE_SC_L::TAGE_SC_L(const TAGE_SC_LParams &p)
79 : LTAGE(p), statisticalCorrector(p.statistical_corrector)
80{
81}
82
85{
86 return new BranchInfo(*this);
87}
88void
90{
91 unsigned numHistLengths = nHistoryTables/2;
93 histLengths[numHistLengths] = maxHist;
94
95 // This calculates the different history lenghts
96 // there are only numHistLengths different lengths
97 // They are initially set to the lower half of histLengths
98 for (int i = 2; i <= numHistLengths; i++) {
99 histLengths[i] = (int) (((double) minHist *
100 pow ((double) (maxHist) / (double) minHist,
101 (double) (i - 1) / (double) ((numHistLengths - 1))))
102 + 0.5);
103 }
104
105 // This copies and duplicates the values from the lower half of the table
106 // Ex: 4, 6, 9, 13 would get exanded to 4, 4, 6, 6, 9, 9, 13, 13
107 for (int i = nHistoryTables; i > 1; i--)
108 {
109 histLengths[i] = histLengths[(i + 1) / 2];
110 }
111
112 for (int i = 1; i <= nHistoryTables; i++)
113 {
114 tagTableTagWidths.push_back(
116
118 }
119}
120
121void
123{
124 // Trick! We only allocate entries for tables 1 and firstLongTagTable and
125 // make the other tables point to these allocated entries
126
130 for (int i = 2; i < firstLongTagTable; ++i) {
131 gtable[i] = gtable[1];
132 }
133 for (int i = firstLongTagTable + 1; i <= nHistoryTables; ++i) {
135 }
136}
137
138void
141{
142 // computes the table addresses and the partial tags
143
144 for (int i = 1; i <= nHistoryTables; i += 2) {
145 tableIndices[i] = gindex(tid, pc, i);
146 tableTags[i] = gtag(tid, pc, i);
147 tableTags[i + 1] = tableTags[i];
148 tableIndices[i + 1] = tableIndices[i] ^
149 (tableTags[i] & ((1 << logTagTableSizes[i]) - 1));
150
151 bi->tableTags[i] = tableTags[i];
152 bi->tableTags[i+1] = tableTags[i+1];
153 }
154
155 Addr t = (pc ^ (threadHistory[tid].pathHist &
156 ((1 << histLengths[firstLongTagTable]) - 1)))
158
159 for (int i = firstLongTagTable; i <= nHistoryTables; i++) {
160 if (noSkip[i]) {
162 bi->tableIndices[i] = tableIndices[i];
163 t++;
165 }
166 }
167
168 t = (pc ^ (threadHistory[tid].pathHist & ((1 << histLengths[1]) - 1)))
170
171 for (int i = 1; i <= firstLongTagTable - 1; i++) {
172 if (noSkip[i]) {
174 bi->tableIndices[i] = tableIndices[i];
175 t++;
177 }
178 }
179}
180
181unsigned
183{
184 BranchInfo *tbi = static_cast<BranchInfo *>(bi);
185 unsigned idx;
186 idx = ((((bi->hitBank-1)/8)<<1)+tbi->altConf) % (numUseAltOnNa-1);
187 return idx;
188}
189
190int
192{
193 int index;
194 int hlen = (histLengths[bank] > pathHistBits) ? pathHistBits :
195 histLengths[bank];
196 unsigned int shortPc = pc;
197
198 // pc is not shifted by instShiftAmt in this implementation
199 index = shortPc ^
200 (shortPc >> ((int) abs(logTagTableSizes[bank] - bank) + 1)) ^
201 threadHistory[tid].computeIndices[bank].comp ^
202 F(threadHistory[tid].pathHist, hlen, bank);
203
204 index = gindex_ext(index, bank);
205
206 return (index & ((1ULL << (logTagTableSizes[bank])) - 1));
207}
208
209int
210TAGE_SC_L_TAGE::F(int a, int size, int bank) const
211{
212 int a1, a2;
213
214 a = a & ((1ULL << size) - 1);
215 a1 = (a & ((1ULL << logTagTableSizes[bank]) - 1));
216 a2 = (a >> logTagTableSizes[bank]);
217
218 if (bank < logTagTableSizes[bank]) {
219 a2 = ((a2 << bank) & ((1ULL << logTagTableSizes[bank]) - 1))
220 + (a2 >> (logTagTableSizes[bank] - bank));
221 }
222
223 a = a1 ^ a2;
224
225 if (bank < logTagTableSizes[bank]) {
226 a = ((a << bank) & ((1ULL << logTagTableSizes[bank]) - 1))
227 + (a >> (logTagTableSizes[bank] - bank));
228 }
229
230 return a;
231}
232
233int
235{
236 return ((pc ^ (pc >> instShiftAmt)) &
237 ((1ULL << (logTagTableSizes[0])) - 1));
238}
239
240void
242 ThreadHistory& tHist, int brtype, bool taken, Addr branch_pc, Addr target)
243{
244 // TAGE update
245 int tmp = ((branch_pc ^ (branch_pc >> instShiftAmt))) ^ taken;
246 int path = branch_pc ^ (branch_pc >> instShiftAmt)
247 ^ (branch_pc >> (instShiftAmt+2));
248 if ((brtype == 3) & taken) {
249 tmp = (tmp ^ (target >> instShiftAmt));
250 path = path ^ (target >> instShiftAmt) ^ (target >> (instShiftAmt+2));
251 }
252
253 // some branch types use 3 bits in global history, the others just 2
254 int maxt = (brtype == 2) ? 3 : 2;
255
256 for (int t = 0; t < maxt; t++) {
257 bool dir = (tmp & 1);
258 tmp >>= 1;
259 int pathbit = (path & 127);
260 path >>= 1;
261 updateGHist(tHist.gHist, dir, tHist.globalHistory, tHist.ptGhist);
262 tHist.pathHist = (tHist.pathHist << 1) ^ pathbit;
263 if (truncatePathHist) {
264 // The 8KB implementation does not do this truncation
265 tHist.pathHist = (tHist.pathHist & ((1ULL << pathHistBits) - 1));
266 }
267 for (int i = 1; i <= nHistoryTables; i++) {
268 tHist.computeIndices[i].update(tHist.gHist);
269 tHist.computeTags[0][i].update(tHist.gHist);
270 tHist.computeTags[1][i].update(tHist.gHist);
271 }
272 }
273}
274
275void
277 ThreadID tid, Addr branch_pc, bool taken, TAGEBase::BranchInfo* b,
278 bool speculative, const StaticInstPtr &inst, Addr target)
279{
280 if (speculative != speculativeHistUpdate) {
281 return;
282 }
283 // speculation is not implemented
284 assert(! speculative);
285
286 ThreadHistory& tHist = threadHistory[tid];
287
288 int brtype = inst->isDirectCtrl() ? 0 : 2;
289 if (! inst->isUncondCtrl()) {
290 ++brtype;
291 }
292 updatePathAndGlobalHistory(tHist, brtype, taken, branch_pc, target);
293
294 DPRINTF(TageSCL, "Updating global histories with branch:%lx; taken?:%d, "
295 "path Hist: %x; pointer:%d\n", branch_pc, taken, tHist.pathHist,
296 tHist.ptGhist);
297}
298
299void
301 Addr target)
302{
303 fatal("Speculation is not implemented");
304}
305
306void
307TAGE_SC_L_TAGE::adjustAlloc(bool & alloc, bool taken, bool pred_taken)
308{
309 // Do not allocate too often if the prediction is ok
310 if ((taken == pred_taken) && ((rng->random<int>() & 31) != 0)) {
311 alloc = false;
312 }
313}
314
315int
317{
318 int a = 1;
319 if ((rng->random<int>() & 127) < 32) {
320 a = 2;
321 }
322 return ((((bi->hitBank - 1 + 2 * a) & 0xffe)) ^
323 (rng->random<int>() & 1));
324}
325
326void
328{
329 //just the best formula for the Championship:
330 //In practice when one out of two entries are useful
331 if (tCounter < 0) {
332 tCounter = 0;
333 }
334
335 if (tCounter >= ((1ULL << logUResetPeriod))) {
336 // Update the u bits for the short tags table
337 for (int j = 0; j < (shortTagsTageFactor*(1<<logTagTableSize)); j++) {
338 resetUctr(gtable[1][j].u);
339 }
340
341 // Update the u bits for the long tags table
342 for (int j = 0; j < (longTagsTageFactor*(1<<logTagTableSize)); j++) {
344 }
345
346 tCounter = 0;
347 }
348}
349
350bool
352{
354 static_cast<TAGE_SC_L_TAGE::BranchInfo *>(tage_bi);
355
356 int bim = (btablePrediction[bi->bimodalIndex] << 1)
358
359 bi->highConf = (bim == 0) || (bim == 3);
360 bi->lowConf = ! bi->highConf;
361 bi->altConf = bi->highConf;
362 bi->medConf = false;
363 return TAGEBase::getBimodePred(pc, tage_bi);
364}
365
366void
368{
369 TAGE_SC_L_TAGE::BranchInfo *tage_scl_bi =
370 static_cast<TAGE_SC_L_TAGE::BranchInfo *>(bi);
371 int8_t ctr = gtable[bi->altBank][bi->altBankIndex].ctr;
372 tage_scl_bi->altConf = (abs(2*ctr + 1) > 1);
373}
374
375bool
376TAGE_SC_L::predict(ThreadID tid, Addr pc, bool cond_branch, void* &b)
377{
381 b = (void*)(bi);
382
383 bool pred_taken = tage->tagePredict(tid, pc, cond_branch,
384 bi->tageBranchInfo);
385 pred_taken = loopPredictor->loopPredict(tid, pc, cond_branch,
386 bi->lpBranchInfo, pred_taken,
388
389 if (bi->lpBranchInfo->loopPredUsed) {
390 bi->tageBranchInfo->provider = LOOP;
391 }
392
393 TAGE_SC_L_TAGE::BranchInfo* tage_scl_bi =
394 static_cast<TAGE_SC_L_TAGE::BranchInfo *>(bi->tageBranchInfo);
395
396 // Copy the confidences computed by TAGE
397 bi->scBranchInfo->lowConf = tage_scl_bi->lowConf;
398 bi->scBranchInfo->highConf = tage_scl_bi->highConf;
399 bi->scBranchInfo->altConf = tage_scl_bi->altConf;
400 bi->scBranchInfo->medConf = tage_scl_bi->medConf;
401
402 bool use_tage_ctr = bi->tageBranchInfo->hitBank > 0;
403 int8_t tage_ctr = use_tage_ctr ?
404 tage->getCtr(tage_scl_bi->hitBank, tage_scl_bi->hitBankIndex) : 0;
405 bool bias = (bi->tageBranchInfo->longestMatchPred !=
406 bi->tageBranchInfo->altTaken);
407
408 pred_taken = statisticalCorrector->scPredict(tid, pc, cond_branch,
409 bi->scBranchInfo, pred_taken, bias, use_tage_ctr, tage_ctr,
410 tage->getTageCtrBits(), bi->tageBranchInfo->hitBank,
411 bi->tageBranchInfo->altBank, tage->getPathHist(tid));
412
413 if (bi->scBranchInfo->usedScPred) {
414 bi->tageBranchInfo->provider = SC;
415 }
416
417 // record final prediction
418 bi->lpBranchInfo->predTaken = pred_taken;
419
420 return pred_taken;
421}
422
423void
424TAGE_SC_L::update(ThreadID tid, Addr pc, bool taken, void *&bp_history,
425 bool squashed, const StaticInstPtr & inst, Addr target)
426{
427 assert(bp_history);
428
429 TageSCLBranchInfo* bi = static_cast<TageSCLBranchInfo*>(bp_history);
431 static_cast<TAGE_SC_L_TAGE::BranchInfo *>(bi->tageBranchInfo);
432
433 if (squashed) {
435 // This restores the global history, then update it
436 // and recomputes the folded histories.
437 tage->squash(tid, taken, tage_bi, target);
438 if (bi->tageBranchInfo->condBranch) {
439 loopPredictor->squashLoop(bi->lpBranchInfo);
440 }
441 }
442 return;
443 }
444
445 int nrand = rng->random<int>() & 3;
446 if (tage_bi->condBranch) {
447 DPRINTF(TageSCL, "Updating tables for branch:%lx; taken?:%d\n",
448 pc, taken);
449 tage->updateStats(taken, bi->tageBranchInfo);
450
451 loopPredictor->updateStats(taken, bi->lpBranchInfo);
452
453 statisticalCorrector->updateStats(taken, bi->scBranchInfo);
454
455 bool bias = (bi->tageBranchInfo->longestMatchPred !=
456 bi->tageBranchInfo->altTaken);
458 bi->scBranchInfo, target, bias, bi->tageBranchInfo->hitBank,
459 bi->tageBranchInfo->altBank, tage->getPathHist(tid));
460
461 loopPredictor->condBranchUpdate(tid, pc, taken,
462 bi->tageBranchInfo->tagePred, bi->lpBranchInfo, instShiftAmt);
463
464 tage->condBranchUpdate(tid, pc, taken, bi->tageBranchInfo,
465 nrand, target, bi->lpBranchInfo->predTaken);
466 }
467
470 bi->scBranchInfo, target);
471
472 tage->updateHistories(tid, pc, taken, bi->tageBranchInfo, false,
473 inst, target);
474 }
475
476 delete bi;
477 bp_history = nullptr;
478}
479
480} // namespace branch_prediction
481} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:209
static std::stack< std::string > path
Definition serialize.hh:315
bool isDirectCtrl() const
bool isUncondCtrl() const
const unsigned instShiftAmt
Number of bits to shift instructions by for predictor addresses.
LoopPredictor * loopPredictor
The loop predictor object.
Definition ltage.hh:93
void updateStats(bool taken, BranchInfo *bi)
Update the stats.
void condBranchUpdate(ThreadID tid, Addr branch_pc, bool taken, bool tage_pred, BranchInfo *bi, unsigned instShiftAmt)
Update LTAGE for conditional branches.
virtual bool calcConf(int index) const
bool loopPredict(ThreadID tid, Addr branch_pc, bool cond_branch, BranchInfo *bi, bool prev_pred_taken, unsigned instShiftAmt)
Get the loop prediction.
virtual void scHistoryUpdate(Addr branch_pc, const StaticInstPtr &inst, bool taken, BranchInfo *tage_bi, Addr corrTarget)
virtual bool scPredict(ThreadID tid, Addr branch_pc, bool cond_branch, BranchInfo *bi, bool prev_pred_taken, bool bias_bit, bool use_conf_ctr, int8_t conf_ctr, unsigned conf_bits, int hitBank, int altBank, int64_t phist, int init_lsum=0)
virtual void condBranchUpdate(ThreadID tid, Addr branch_pc, bool taken, BranchInfo *bi, Addr corrTarget, bool bias_bit, int hitBank, int altBank, int64_t phist)
virtual void updateHistories(ThreadID tid, Addr branch_pc, bool taken, BranchInfo *b, bool speculative, const StaticInstPtr &inst=nullStaticInstPtr, Addr target=MaxAddr)
(Speculatively) updates global histories (path and direction).
Definition tage_base.cc:588
virtual void resetUctr(uint8_t &u)
Algorithm for resetting a single U counter.
Definition tage_base.cc:508
virtual void updateStats(bool taken, BranchInfo *bi)
Update the stats.
Definition tage_base.cc:662
const unsigned logRatioBiModalHystEntries
Definition tage_base.hh:424
std::vector< bool > btableHysteresis
Definition tage_base.hh:437
void updateGHist(uint8_t *&h, bool dir, uint8_t *tab, int &PT)
(Speculatively) updates the global branch history.
Definition tage_base.cc:322
std::vector< bool > btablePrediction
Definition tage_base.hh:436
std::vector< ThreadHistory > threadHistory
Definition tage_base.hh:464
virtual bool getBimodePred(Addr pc, BranchInfo *bi) const
Get a branch prediction from the bimodal predictor.
Definition tage_base.cc:293
int8_t getCtr(int hitBank, int hitBankIndex) const
Definition tage_base.cc:768
std::vector< int > logTagTableSizes
Definition tage_base.hh:434
virtual void squash(ThreadID tid, bool taken, BranchInfo *bi, Addr target)
Restores speculatively updated path and direction histories.
Definition tage_base.cc:629
bool tagePredict(ThreadID tid, Addr branch_pc, bool cond_branch, BranchInfo *bi)
TAGE prediction called from TAGE::predict.
Definition tage_base.cc:360
int getPathHist(ThreadID tid) const
Definition tage_base.cc:780
std::vector< unsigned > tagTableTagWidths
Definition tage_base.hh:433
virtual void condBranchUpdate(ThreadID tid, Addr branch_pc, bool taken, BranchInfo *bi, int nrand, Addr corrTarget, bool pred, bool preAdjustAlloc=false)
Update TAGE for conditional branches.
Definition tage_base.cc:514
virtual bool optionalAgeInc() const override
Definition tage_sc_l.cc:73
virtual bool calcConf(int index) const override
Definition tage_sc_l.cc:66
void updatePathAndGlobalHistory(ThreadHistory &tHist, int brtype, bool taken, Addr branch_pc, Addr target)
Definition tage_sc_l.cc:241
void extraAltCalc(TAGEBase::BranchInfo *bi) override
Extra steps for calculating altTaken For this base TAGE class it does nothing.
Definition tage_sc_l.cc:367
void calculateIndicesAndTags(ThreadID tid, Addr branch_pc, TAGEBase::BranchInfo *bi) override
On a prediction, calculates the TAGE indices and tags for all the different history lengths.
Definition tage_sc_l.cc:139
int bindex(Addr pc_in) const override
Computes the index used to access the bimodal table.
Definition tage_sc_l.cc:234
int calcDep(TAGEBase::BranchInfo *bi)
Definition tage_sc_l.cc:316
bool getBimodePred(Addr branch_pc, TAGEBase::BranchInfo *tage_bi) const override
Get a branch prediction from the bimodal predictor.
Definition tage_sc_l.cc:351
virtual TAGEBase::BranchInfo * makeBranchInfo() override
Definition tage_sc_l.cc:84
int gindex(ThreadID tid, Addr pc, int bank) const override
Computes the index used to access a partially tagged table.
Definition tage_sc_l.cc:191
virtual int gindex_ext(int index, int bank) const =0
int F(int phist, int size, int bank) const override
Utility function to shuffle the path history depending on which tagged table we are accessing.
Definition tage_sc_l.cc:210
void calculateParameters() override
Calculates the history lengths and some other paramters in derived classes.
Definition tage_sc_l.cc:89
void squash(ThreadID tid, bool taken, TAGEBase::BranchInfo *bi, Addr target) override
Restores speculatively updated path and direction histories.
Definition tage_sc_l.cc:300
void adjustAlloc(bool &alloc, bool taken, bool pred_taken) override
Extra calculation to tell whether TAGE allocaitons may happen or not on an update For this base TAGE ...
Definition tage_sc_l.cc:307
void buildTageTables() override
Instantiates the TAGE table entries.
Definition tage_sc_l.cc:122
unsigned getUseAltIdx(TAGEBase::BranchInfo *bi, Addr branch_pc) override
Calculation of the index for useAltPredForNewlyAllocated On this base TAGE implementation it is alway...
Definition tage_sc_l.cc:182
virtual uint16_t gtag(ThreadID tid, Addr pc, int bank) const override=0
Computes the partial tag of a tagged table.
void updateHistories(ThreadID tid, Addr branch_pc, bool taken, TAGEBase::BranchInfo *b, bool speculative, const StaticInstPtr &inst, Addr target) override
(Speculatively) updates global histories (path and direction).
Definition tage_sc_l.cc:276
void handleUReset() override
Handles the U bits reset.
Definition tage_sc_l.cc:327
bool predict(ThreadID tid, Addr pc, bool cond_branch, void *&b) override
Get a branch prediction from LTAGE.
Definition tage_sc_l.cc:376
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 tage_sc_l.cc:424
TAGE_SC_L(const TAGE_SC_LParams &params)
Definition tage_sc_l.cc:78
StatisticalCorrector * statisticalCorrector
Definition tage_sc_l.hh:174
Random::RandomPtr rng
Definition tage.hh:82
#define fatal(...)
This implements a cprintf based fatal() function.
Definition logging.hh:200
Bitfield< 22 > a1
Bitfield< 5 > t
Definition misc_types.hh:71
Bitfield< 7 > b
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 20 > tbi
Bitfield< 8 > a
Definition misc_types.hh:66
Bitfield< 22 > u
Bitfield< 4 > pc
Bitfield< 30, 0 > index
Bitfield< 0 > p
Bitfield< 20, 16 > bi
Definition types.hh:80
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

Generated on Mon Jan 13 2025 04:28:32 for gem5 by doxygen 1.9.8