gem5 [DEVELOP-FOR-25.0]
Loading...
Searching...
No Matches
statistical_corrector.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2018 Metempsy Technology Consulting
3 * Copyright (c) 2024 Technical University of Munich
4 * All rights reserved.
5 *
6 * Copyright (c) 2006 INRIA (Institut National de Recherche en
7 * Informatique et en Automatique / French National Research Institute
8 * for Computer Science and Applied Mathematics)
9 *
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions are
14 * met: redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer;
16 * redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution;
19 * neither the name of the copyright holders nor the names of its
20 * contributors may be used to endorse or promote products derived from
21 * this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 *
35 * Author: André Seznec, Pau Cabre, Javier Bueno
36 *
37 */
38
39/*
40 * Statistical corrector base class
41 */
42
44
45#include "params/StatisticalCorrector.hh"
46
47namespace gem5
48{
49
50namespace branch_prediction
51{
52
54 const StatisticalCorrectorParams &p)
55 : SimObject(p),
60 bwnb(p.bwnb),
62 bwm(p.bwm),
63 lnb(p.lnb),
65 lm(p.lm),
66 inb(p.inb),
68 im(p.im),
76 firstH(0),
77 secondH(0),
78 stats(this)
79{
80 wb.resize(1 << logSizeUps, 4);
81
82 initGEHLTable(lnb, lm, lgehl, logLnb, wl, p.lWeightInitValue);
83 initGEHLTable(bwnb, bwm, bwgehl, logBwnb, wbw, p.bwWeightInitValue);
84 initGEHLTable(inb, im, igehl, logInb, wi, p.iWeightInitValue);
85
86 updateThreshold = 35 << 3;
87
88 pUpdateThreshold.resize(1 << logSizeUp, p.initialUpdateThresholdValue);
89
90 bias.resize(1 << logBias);
91 biasSK.resize(1 << logBias);
92 biasBank.resize(1 << logBias);
93}
94
100
106
107void
109{
110 for (int j = 0; j < (1 << logBias); j++) {
111 switch (j & 3) {
112 case 0:
113 bias[j] = -32;
114 biasSK[j] = -8;
115 biasBank[j] = -32;
116 break;
117 case 1:
118 bias[j] = 31;
119 biasSK[j] = 7;
120 biasBank[j] = 31;
121 break;
122 case 2:
123 bias[j] = -1;
124 biasSK[j] = -32;
125 biasBank[j] = -1;
126 break;
127 case 3:
128 bias[j] = 0;
129 biasSK[j] = 31;
130 biasBank[j] = 0;
131 break;
132 }
133 }
134}
135
136void
138 std::vector<int> lengths,
139 std::vector<int8_t> *&table,
140 unsigned logNumEntries,
141 std::vector<int8_t> &w, int8_t wInitValue)
142{
143 assert(lengths.size() == numLenghts);
144 if (numLenghts == 0) {
145 return;
146 }
147 table = new std::vector<int8_t> [numLenghts];
148 for (int i = 0; i < numLenghts; ++i) {
149 table[i].resize(1 << logNumEntries, 0);
150 for (int j = 0; j < ((1 << logNumEntries) - 1); ++j) {
151 if (! (j & 1)) {
152 table[i][j] = -1;
153 }
154 }
155 }
156
157 w.resize(1 << logSizeUps, wInitValue);
158}
159
160unsigned
162 bool bias) const
163{
164 Addr shifted_pc = branch_pc >> instShiftAmt;
165 return (((((shifted_pc ^ (shifted_pc >> 2)) << 1)
166 ^ (bi->lowConf & bias)) << 1) + bi->predBeforeSC)
167 & ((1 << logBias) - 1);
168}
169
170unsigned
172{
173 Addr shifted_pc = branch_pc >> instShiftAmt;
174 return (((((shifted_pc ^ (shifted_pc >> (logBias - 2))) << 1)
175 ^ bi->highConf) << 1) + bi->predBeforeSC)
176 & ((1 << logBias) - 1);
177}
178
179unsigned
181{
182 Addr shifted_pc = branch_pc >> instShiftAmt;
183 return ((shifted_pc ^ (shifted_pc >> 2)) & ((1 << logSizeUp) - 1));
184}
185
186unsigned
188{
189 Addr shifted_pc = branch_pc >> instShiftAmt;
190 return ((shifted_pc ^ (shifted_pc >> 2)) & ((1 << logSizeUps) - 1));
191}
192
193int64_t
194StatisticalCorrector::gIndex(Addr branch_pc, int64_t bhist, int logs, int nbr,
195 int i)
196{
197 return (((int64_t) branch_pc >> instShiftAmt) ^
198 bhist ^ (bhist >> (8 - i)) ^
199 (bhist >> (16 - 2 * i)) ^ (bhist >> (24 - 3 * i)) ^
200 (bhist >> (32 - 3 * i)) ^ (bhist >> (40 - 4 * i))) &
201 ((1 << (logs - gIndexLogsSubstr(nbr, i))) - 1);
202}
203
204int
205StatisticalCorrector::gPredict(Addr branch_pc, int64_t hist,
206 std::vector<int> &length,
207 std::vector<int8_t> *tab, int nbr, int logs,
209{
210 int percsum = 0;
211 for (int i = 0; i < nbr; i++) {
212 int64_t bhist = hist & ((int64_t) ((1 << length[i]) - 1));
213 int64_t index = gIndex(branch_pc, bhist, logs, nbr, i);
214 int8_t ctr = tab[i][index];
215 percsum += (2 * ctr + 1);
216 }
217 percsum = (1 + (w[getIndUpds(branch_pc)] >= 0)) * percsum;
218 return percsum;
219}
220
221void
222StatisticalCorrector::gUpdate(Addr branch_pc, bool taken, int64_t hist,
223 std::vector<int> &length,
224 std::vector<int8_t> *tab, int nbr, int logs,
226{
227 int percsum = 0;
228 for (int i = 0; i < nbr; i++) {
229 int64_t bhist = hist & ((int64_t) ((1 << length[i]) - 1));
230 int64_t index = gIndex(branch_pc, bhist, logs, nbr, i);
231 percsum += (2 * tab[i][index] + 1);
232 ctrUpdate(tab[i][index], taken, scCountersWidth);
233 }
234
235 int xsum = bi->lsum - ((w[getIndUpds(branch_pc)] >= 0)) * percsum;
236 if ((xsum + percsum >= 0) != (xsum >= 0)) {
237 ctrUpdate(w[getIndUpds(branch_pc)], ((percsum >= 0) == taken),
239 }
240}
241
242bool
243StatisticalCorrector::scPredict(ThreadID tid, Addr branch_pc, bool cond_branch,
244 BranchInfo *bi, bool prev_pred_taken,
245 bool bias_bit, bool use_conf_ctr,
246 int8_t conf_ctr, unsigned conf_bits,
247 int hitBank, int altBank, int init_lsum)
248{
249 bool pred_taken = prev_pred_taken;
250 if (cond_branch) {
251
252 bi->predBeforeSC = prev_pred_taken;
253 int lsum = init_lsum;
254
255 lsum += calcBias(branch_pc, bi, bias_bit,
256 use_conf_ctr, conf_ctr, conf_bits, hitBank, altBank);
257
258 // Record the history state to be able to recover
259 // The gPredictions function will use the recorded state to
260 // make the predictions
261 scRecordHistState(branch_pc, bi);
262
263 int thres = gPredictions(tid, branch_pc, bi, lsum);
264
265 // These will be needed at update time
266 bi->lsum = lsum;
267 bi->thres = thres;
268
269 bool scPred = (lsum >= 0);
270
271 if (pred_taken != scPred) {
272 bool useScPred = true;
273 //Choser uses TAGE confidence and |LSUM|
274 if (bi->highConf) {
275 if (abs (lsum) < (thres / 4)) {
276 useScPred = false;
277 } else if (abs (lsum) < (thres / 2)) {
278 useScPred = (secondH < 0);
279 }
280 }
281
282 if (bi->medConf) {
283 if (abs (lsum) < (thres / 4)) {
284 useScPred = (firstH < 0);
285 }
286 }
287
288 bi->usedScPred = useScPred;
289 if (useScPred) {
290 pred_taken = scPred;
291 bi->scPred = scPred;
292 }
293 }
294 }
295
296 return pred_taken;
297}
298
299int
301 bool use_conf_ctr, int8_t conf_ctr,
302 unsigned conf_bits, int hitBank, int altBank)
303{
304 // first calc/update the confidences from the TAGE prediction
305 if (use_conf_ctr) {
306 bi->lowConf = (abs(2 * conf_ctr + 1) == 1);
307 bi->medConf = (abs(2 * conf_ctr + 1) == 5);
308 bi->highConf = (abs(2 * conf_ctr + 1) >= (1<<conf_bits) - 1);
309 }
310
311 int lsum = 0;
312
313 int8_t ctr = bias[getIndBias(branch_pc, bi, bias_bit)];
314 lsum += (2 * ctr + 1);
315 ctr = biasSK[getIndBiasSK(branch_pc, bi)];
316 lsum += (2 * ctr + 1);
317 ctr = biasBank[getIndBiasBank(branch_pc, bi, hitBank, altBank)];
318 lsum += (2 * ctr + 1);
319
320 lsum = (1 + (wb[getIndUpds(branch_pc)] >= 0)) * lsum;
321 return lsum;
322}
323
324
325void
326StatisticalCorrector::updateHistories(Addr branch_pc, bool speculative,
327 const StaticInstPtr &inst, bool taken,
328 BranchInfo *bi, Addr target,
329 int64_t phist)
330{
331 if (speculative != speculativeHistUpdate) {
332 return;
333 }
334
335 // If this is the first time we see this branch record the current
336 // state of the history to be able to recover.
337 if (speculativeHistUpdate && (!bi->modified)) {
338 scRecordHistState(branch_pc, bi);
339 }
340
341 // In case the branch already updated the history
342 // we need to revert the previous update first.
343 if (bi->modified) {
345 }
346
347 // Update the SC histories
348 scHistoryUpdate(branch_pc, inst, taken, target, phist);
349 bi->modified = true;
350}
351
352void
354 const StaticInstPtr &inst, bool taken,
355 Addr target, int64_t phist)
356{
357 // Update the path history from TAGE
358 scHistory->pHist = phist;
359 int brtype = inst->isDirectCtrl() ? 0 : 2;
360 if (! inst->isUncondCtrl()) {
361 ++brtype;
362 }
363 // Non speculative SC histories update
364 if (brtype & 1) {
365 if (target < branch_pc) {
366 //This branch corresponds to a loop
367 if (!taken) {
368 //exit of the "loop"
369 scHistory->imliCount = 0;
370 } else {
371 if (scHistory->imliCount < ((1 << im[0]) - 1)) {
372 scHistory->imliCount++;
373 }
374 }
375 }
376
377 scHistory->bwHist = (scHistory->bwHist << 1) +
378 (taken & (target < branch_pc));
379 scHistory->updateLocalHistory(1, branch_pc, taken);
380 }
381}
382
383void
385{
386 bi->pc = branch_pc;
387 bi->bwHist = scHistory->bwHist;
388 bi->imliCount = scHistory->imliCount;
389 bi->pHist = scHistory->pHist;
390 bi->localHistories[1] = scHistory->getLocalHistory(1, branch_pc);
391}
392
393bool
395{
396 if (!bi->modified) {
397 return false;
398 }
399 scHistory->bwHist = bi->bwHist;
400 scHistory->imliCount = bi->imliCount;
401 scHistory->setLocalHistory(1, bi->pc, bi->localHistories[1]);
402 return true;
403}
404
405
406void
408 bool taken, BranchInfo *bi,
409 Addr corrTarget, bool b, int hitBank,
410 int altBank)
411{
412
414 // For speculative updates we recalculate the lsum as it might
415 // have changed since the last update
416
417 bi->lsum = calcBias(branch_pc, bi, b, false/* was already recorded*/,
418 0, 0, hitBank, altBank);
419 bi->thres = gPredictions(tid, branch_pc, bi, bi->lsum);
420 }
421
422 bool scPred = (bi->lsum >= 0);
423
424 if (bi->predBeforeSC != scPred) {
425 if (abs(bi->lsum) < bi->thres) {
426 if (bi->highConf) {
427 if ((abs(bi->lsum) < bi->thres / 2)) {
428 if ((abs(bi->lsum) >= bi->thres / 4)) {
429 ctrUpdate(secondH, (bi->predBeforeSC == taken),
431 }
432 }
433 }
434 }
435 if (bi->medConf) {
436 if ((abs(bi->lsum) < bi->thres / 4)) {
437 ctrUpdate(firstH, (bi->predBeforeSC == taken),
439 }
440 }
441 }
442
443 if ((scPred != taken) || ((abs(bi->lsum) < bi->thres))) {
445 ctrUpdate(pUpdateThreshold[getIndUpd(branch_pc)], (scPred != taken),
447
448 unsigned indUpds = getIndUpds(branch_pc);
449 unsigned indBias = getIndBias(branch_pc, bi, b);
450 unsigned indBiasSK = getIndBiasSK(branch_pc, bi);
451 unsigned indBiasBank = getIndBiasBank(branch_pc, bi, hitBank, altBank);
452
453 int xsum = bi->lsum -
454 ((wb[indUpds] >= 0) * ((2 * bias[indBias] + 1) +
455 (2 * biasSK[indBiasSK] + 1) +
456 (2 * biasBank[indBiasBank] + 1)));
457
458 if ((xsum + ((2 * bias[indBias] + 1) + (2 * biasSK[indBiasSK] + 1) +
459 (2 * biasBank[indBiasBank] + 1)) >= 0) != (xsum >= 0))
460 {
461 ctrUpdate(wb[indUpds],
462 (((2 * bias[indBias] + 1) +
463 (2 * biasSK[indBiasSK] + 1) +
464 (2 * biasBank[indBiasBank] + 1) >= 0) == taken),
466 }
467
468 ctrUpdate(bias[indBias], taken, scCountersWidth);
469 ctrUpdate(biasSK[indBiasSK], taken, scCountersWidth);
470 ctrUpdate(biasBank[indBiasBank], taken, scCountersWidth);
471
472 gUpdates(tid, branch_pc, taken, bi);
473 }
474}
475
476void
478{
479 if (taken == bi->scPred) {
480 stats.correct++;
481 } else {
482 stats.wrong++;
483 }
484}
485
486void
492
493size_t
495{
496 // Not implemented
497 return 0;
498}
499
501 statistics::Group *parent)
502 : statistics::Group(parent),
503 ADD_STAT(correct, statistics::units::Count::get(),
504 "Number of time the SC predictor is the provider and the "
505 "prediction is correct"),
506 ADD_STAT(wrong, statistics::units::Count::get(),
507 "Number of time the SC predictor is the provider and the "
508 "prediction is wrong")
509{
510}
511
512} // namespace branch_prediction
513} // namespace gem5
bool isDirectCtrl() const
bool isUncondCtrl() const
void initGEHLTable(unsigned numLenghts, std::vector< int > lengths, std::vector< int8_t > *&table, unsigned logNumEntries, std::vector< int8_t > &w, int8_t wInitValue)
virtual int gPredictions(ThreadID tid, Addr branch_pc, BranchInfo *bi, int &lsum)=0
gem5::branch_prediction::StatisticalCorrector::StatisticalCorrectorStats stats
virtual unsigned getIndBiasSK(Addr branch_pc, BranchInfo *bi) const
int gPredict(Addr branch_pc, int64_t hist, std::vector< int > &length, std::vector< int8_t > *tab, int nbr, int logs, std::vector< int8_t > &w)
virtual void scHistoryUpdate(Addr branch_pc, const StaticInstPtr &inst, bool taken, Addr target, int64_t phist)
virtual void scRecordHistState(Addr branch_pc, BranchInfo *bi)
StatisticalCorrector(const StatisticalCorrectorParams &p)
virtual unsigned getIndUpd(Addr branch_pc) const
int calcBias(Addr branch_pc, BranchInfo *bi, bool bias_bit, bool use_conf_ctr, int8_t conf_ctr, unsigned conf_bits, int hitBank, int altBank)
virtual unsigned getIndBias(Addr branch_pc, BranchInfo *bi, bool b) const
void ctrUpdate(T &ctr, bool taken, int nbits)
void updateHistories(Addr branch_pc, bool speculative, const StaticInstPtr &inst, bool taken, BranchInfo *bi, Addr target, int64_t phist)
virtual void gUpdate(Addr branch_pc, bool taken, int64_t hist, std::vector< int > &length, std::vector< int8_t > *tab, int nbr, int logs, std::vector< int8_t > &w, BranchInfo *bi)
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
virtual unsigned getIndBiasBank(Addr branch_pc, BranchInfo *bi, int hitBank, int altBank) const =0
virtual void condBranchUpdate(ThreadID tid, Addr branch_pc, bool taken, BranchInfo *bi, Addr corrTarget, bool bias_bit, int hitBank, int altBank)
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, int init_lsum=0)
virtual int gIndexLogsSubstr(int nbr, int i)=0
int64_t gIndex(Addr branch_pc, int64_t bhist, int logs, int nbr, int i)
virtual void gUpdates(ThreadID tid, Addr pc, bool taken, BranchInfo *bi)=0
Statistics container.
Definition group.hh:93
STL vector class.
Definition stl.hh:37
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition group.hh:75
SimObject(const Params &p)
Definition sim_object.cc:58
Bitfield< 7 > b
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 30, 0 > index
Bitfield< 0 > p
Bitfield< 0 > w
Bitfield< 20, 16 > bi
Definition types.hh:80
Units for Stats.
Definition units.hh:113
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

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