gem5  v22.1.0.0
statistical_corrector.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018 Metempsy Technology Consulting
3  * All rights reserved.
4  *
5  * Copyright (c) 2006 INRIA (Institut National de Recherche en
6  * Informatique et en Automatique / French National Research Institute
7  * for Computer Science and Applied Mathematics)
8  *
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions are
13  * met: redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer;
15  * redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in the
17  * documentation and/or other materials provided with the distribution;
18  * neither the name of the copyright holders nor the names of its
19  * contributors may be used to endorse or promote products derived from
20  * this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  *
34  * Author: AndrĂ© Seznec, Pau Cabre, Javier Bueno
35  *
36  */
37 
38 /*
39  * Statistical corrector base class
40  */
41 
43 
44 #include "params/StatisticalCorrector.hh"
45 
46 namespace gem5
47 {
48 
49 namespace branch_prediction
50 {
51 
53  const StatisticalCorrectorParams &p)
54  : SimObject(p),
55  logBias(p.logBias),
56  logSizeUp(p.logSizeUp),
57  logSizeUps(logSizeUp / 2),
58  numEntriesFirstLocalHistories(p.numEntriesFirstLocalHistories),
59  bwnb(p.bwnb),
60  logBwnb(p.logBwnb),
61  bwm(p.bwm),
62  lnb(p.lnb),
63  logLnb(p.logLnb),
64  lm(p.lm),
65  inb(p.inb),
66  logInb(p.logInb),
67  im(p.im),
68  chooserConfWidth(p.chooserConfWidth),
69  updateThresholdWidth(p.updateThresholdWidth),
70  pUpdateThresholdWidth(p.pUpdateThresholdWidth),
71  extraWeightsWidth(p.extraWeightsWidth),
72  scCountersWidth(p.scCountersWidth),
73  firstH(0),
74  secondH(0),
75  stats(this)
76 {
77  wb.resize(1 << logSizeUps, 4);
78 
79  initGEHLTable(lnb, lm, lgehl, logLnb, wl, p.lWeightInitValue);
80  initGEHLTable(bwnb, bwm, bwgehl, logBwnb, wbw, p.bwWeightInitValue);
81  initGEHLTable(inb, im, igehl, logInb, wi, p.iWeightInitValue);
82 
83  updateThreshold = 35 << 3;
84 
85  pUpdateThreshold.resize(1 << logSizeUp, p.initialUpdateThresholdValue);
86 
87  bias.resize(1 << logBias);
88  biasSK.resize(1 << logBias);
89  biasBank.resize(1 << logBias);
90 }
91 
94 {
95  return new BranchInfo();
96 }
97 
100 {
101  return new SCThreadHistory();
102 }
103 
104 void
106 {
107  for (int j = 0; j < (1 << logBias); j++) {
108  switch (j & 3) {
109  case 0:
110  bias[j] = -32;
111  biasSK[j] = -8;
112  biasBank[j] = -32;
113  break;
114  case 1:
115  bias[j] = 31;
116  biasSK[j] = 7;
117  biasBank[j] = 31;
118  break;
119  case 2:
120  bias[j] = -1;
121  biasSK[j] = -32;
122  biasBank[j] = -1;
123  break;
124  case 3:
125  bias[j] = 0;
126  biasSK[j] = 31;
127  biasBank[j] = 0;
128  break;
129  }
130  }
131 }
132 
133 void
135  std::vector<int> lengths, std::vector<int8_t> * & table,
136  unsigned logNumEntries, std::vector<int8_t> & w, int8_t wInitValue)
137 {
138  assert(lengths.size() == numLenghts);
139  if (numLenghts == 0) {
140  return;
141  }
142  table = new std::vector<int8_t> [numLenghts];
143  for (int i = 0; i < numLenghts; ++i) {
144  table[i].resize(1 << logNumEntries, 0);
145  for (int j = 0; j < ((1 << logNumEntries) - 1); ++j) {
146  if (! (j & 1)) {
147  table[i][j] = -1;
148  }
149  }
150  }
151 
152  w.resize(1 << logSizeUps, wInitValue);
153 }
154 
155 unsigned
157  bool bias) const
158 {
159  return (((((branch_pc ^(branch_pc >>2))<<1) ^ (bi->lowConf & bias)) <<1)
160  + bi->predBeforeSC) & ((1<<logBias) -1);
161 }
162 
163 unsigned
165 {
166  return (((((branch_pc ^ (branch_pc >> (logBias-2)))<<1) ^
167  (bi->highConf))<<1) + bi->predBeforeSC) & ((1<<logBias) -1);
168 }
169 
170 unsigned
172 {
173  return ((branch_pc ^ (branch_pc >>2)) & ((1 << (logSizeUp)) - 1));
174 }
175 
176 unsigned
178 {
179  return ((branch_pc ^ (branch_pc >>2)) & ((1 << (logSizeUps)) - 1));
180 }
181 
182 int64_t
183 StatisticalCorrector::gIndex(Addr branch_pc, int64_t bhist, int logs, int nbr,
184  int i)
185 {
186  return (((int64_t) branch_pc) ^ bhist ^ (bhist >> (8 - i)) ^
187  (bhist >> (16 - 2 * i)) ^ (bhist >> (24 - 3 * i)) ^
188  (bhist >> (32 - 3 * i)) ^ (bhist >> (40 - 4 * i))) &
189  ((1 << (logs - gIndexLogsSubstr(nbr, i))) - 1);
190 }
191 
192 int
193 StatisticalCorrector::gPredict(Addr branch_pc, int64_t hist,
194  std::vector<int> & length, std::vector<int8_t> * tab, int nbr,
195  int logs, std::vector<int8_t> & w)
196 {
197  int percsum = 0;
198  for (int i = 0; i < nbr; i++) {
199  int64_t bhist = hist & ((int64_t) ((1 << length[i]) - 1));
200  int64_t index = gIndex(branch_pc, bhist, logs, nbr, i);
201  int8_t ctr = tab[i][index];
202  percsum += (2 * ctr + 1);
203  }
204  percsum = (1 + (w[getIndUpds(branch_pc)] >= 0)) * percsum;
205  return percsum;
206 }
207 
208 void
209 StatisticalCorrector::gUpdate(Addr branch_pc, bool taken, int64_t hist,
210  std::vector<int> & length, std::vector<int8_t> * tab,
211  int nbr, int logs, std::vector<int8_t> & w,
212  BranchInfo* bi)
213 {
214  int percsum = 0;
215  for (int i = 0; i < nbr; i++) {
216  int64_t bhist = hist & ((int64_t) ((1 << length[i]) - 1));
217  int64_t index = gIndex(branch_pc, bhist, logs, nbr, i);
218  percsum += (2 * tab[i][index] + 1);
219  ctrUpdate(tab[i][index], taken, scCountersWidth);
220  }
221 
222  int xsum = bi->lsum - ((w[getIndUpds(branch_pc)] >= 0)) * percsum;
223  if ((xsum + percsum >= 0) != (xsum >= 0)) {
224  ctrUpdate(w[getIndUpds(branch_pc)], ((percsum >= 0) == taken),
226  }
227 }
228 
229 bool
230 StatisticalCorrector::scPredict(ThreadID tid, Addr branch_pc, bool cond_branch,
231  BranchInfo* bi, bool prev_pred_taken, bool bias_bit,
232  bool use_conf_ctr, int8_t conf_ctr, unsigned conf_bits,
233  int hitBank, int altBank, int64_t phist, int init_lsum)
234 {
235  bool pred_taken = prev_pred_taken;
236  if (cond_branch) {
237 
238  bi->predBeforeSC = prev_pred_taken;
239 
240  // first calc/update the confidences from the TAGE prediction
241  if (use_conf_ctr) {
242  bi->lowConf = (abs(2 * conf_ctr + 1) == 1);
243  bi->medConf = (abs(2 * conf_ctr + 1) == 5);
244  bi->highConf = (abs(2 * conf_ctr + 1) >= (1<<conf_bits) - 1);
245  }
246 
247  int lsum = init_lsum;
248 
249  int8_t ctr = bias[getIndBias(branch_pc, bi, bias_bit)];
250  lsum += (2 * ctr + 1);
251  ctr = biasSK[getIndBiasSK(branch_pc, bi)];
252  lsum += (2 * ctr + 1);
253  ctr = biasBank[getIndBiasBank(branch_pc, bi, hitBank, altBank)];
254  lsum += (2 * ctr + 1);
255 
256  lsum = (1 + (wb[getIndUpds(branch_pc)] >= 0)) * lsum;
257 
258  int thres = gPredictions(tid, branch_pc, bi, lsum, phist);
259 
260  // These will be needed at update time
261  bi->lsum = lsum;
262  bi->thres = thres;
263 
264  bool scPred = (lsum >= 0);
265 
266  if (pred_taken != scPred) {
267  bool useScPred = true;
268  //Choser uses TAGE confidence and |LSUM|
269  if (bi->highConf) {
270  if (abs (lsum) < (thres / 4)) {
271  useScPred = false;
272  } else if (abs (lsum) < (thres / 2)) {
273  useScPred = (secondH < 0);
274  }
275  }
276 
277  if (bi->medConf) {
278  if (abs (lsum) < (thres / 4)) {
279  useScPred = (firstH < 0);
280  }
281  }
282 
283  bi->usedScPred = useScPred;
284  if (useScPred) {
285  pred_taken = scPred;
286  bi->scPred = scPred;
287  }
288  }
289  }
290 
291  return pred_taken;
292 }
293 
294 void
296  const StaticInstPtr &inst, bool taken, BranchInfo * tage_bi,
297  Addr corrTarget)
298 {
299  int brtype = inst->isDirectCtrl() ? 0 : 2;
300  if (! inst->isUncondCtrl()) {
301  ++brtype;
302  }
303  // Non speculative SC histories update
304  if (brtype & 1) {
305  if (corrTarget < branch_pc) {
306  //This branch corresponds to a loop
307  if (!taken) {
308  //exit of the "loop"
309  scHistory->imliCount = 0;
310  } else {
311  if (scHistory->imliCount < ((1 << im[0]) - 1)) {
312  scHistory->imliCount++;
313  }
314  }
315  }
316 
317  scHistory->bwHist = (scHistory->bwHist << 1) +
318  (taken & (corrTarget < branch_pc));
319  scHistory->updateLocalHistory(1, branch_pc, taken);
320  }
321 }
322 
323 void
325  bool taken, BranchInfo *bi, Addr corrTarget, bool b, int hitBank,
326  int altBank, int64_t phist)
327 {
328  bool scPred = (bi->lsum >= 0);
329 
330  if (bi->predBeforeSC != scPred) {
331  if (abs(bi->lsum) < bi->thres) {
332  if (bi->highConf) {
333  if ((abs(bi->lsum) < bi->thres / 2)) {
334  if ((abs(bi->lsum) >= bi->thres / 4)) {
335  ctrUpdate(secondH, (bi->predBeforeSC == taken),
337  }
338  }
339  }
340  }
341  if (bi->medConf) {
342  if ((abs(bi->lsum) < bi->thres / 4)) {
343  ctrUpdate(firstH, (bi->predBeforeSC == taken),
345  }
346  }
347  }
348 
349  if ((scPred != taken) || ((abs(bi->lsum) < bi->thres))) {
350  ctrUpdate(updateThreshold, (scPred != taken), updateThresholdWidth);
351  ctrUpdate(pUpdateThreshold[getIndUpd(branch_pc)], (scPred != taken),
353 
354  unsigned indUpds = getIndUpds(branch_pc);
355  unsigned indBias = getIndBias(branch_pc, bi, b);
356  unsigned indBiasSK = getIndBiasSK(branch_pc, bi);
357  unsigned indBiasBank = getIndBiasBank(branch_pc, bi, hitBank, altBank);
358 
359  int xsum = bi->lsum -
360  ((wb[indUpds] >= 0) * ((2 * bias[indBias] + 1) +
361  (2 * biasSK[indBiasSK] + 1) +
362  (2 * biasBank[indBiasBank] + 1)));
363 
364  if ((xsum + ((2 * bias[indBias] + 1) + (2 * biasSK[indBiasSK] + 1) +
365  (2 * biasBank[indBiasBank] + 1)) >= 0) != (xsum >= 0))
366  {
367  ctrUpdate(wb[indUpds],
368  (((2 * bias[indBias] + 1) +
369  (2 * biasSK[indBiasSK] + 1) +
370  (2 * biasBank[indBiasBank] + 1) >= 0) == taken),
372  }
373 
374  ctrUpdate(bias[indBias], taken, scCountersWidth);
375  ctrUpdate(biasSK[indBiasSK], taken, scCountersWidth);
376  ctrUpdate(biasBank[indBiasBank], taken, scCountersWidth);
377 
378  gUpdates(tid, branch_pc, taken, bi, phist);
379  }
380 }
381 
382 void
384 {
385  if (taken == bi->scPred) {
386  stats.correct++;
387  } else {
388  stats.wrong++;
389  }
390 }
391 
392 void
394 {
396  initBias();
397 }
398 
399 size_t
401 {
402  // Not implemented
403  return 0;
404 }
405 
407  statistics::Group *parent)
408  : statistics::Group(parent),
409  ADD_STAT(correct, statistics::units::Count::get(),
410  "Number of time the SC predictor is the provider and the "
411  "prediction is correct"),
412  ADD_STAT(wrong, statistics::units::Count::get(),
413  "Number of time the SC predictor is the provider and the "
414  "prediction is wrong")
415 {
416 }
417 
418 } // namespace branch_prediction
419 } // namespace gem5
Abstract superclass for simulation objects.
Definition: sim_object.hh:148
bool isDirectCtrl() const
Definition: static_inst.hh:163
bool isUncondCtrl() const
Definition: static_inst.hh:166
void initGEHLTable(unsigned numLenghts, std::vector< int > lengths, std::vector< int8_t > *&table, unsigned logNumEntries, std::vector< int8_t > &w, int8_t wInitValue)
gem5::branch_prediction::StatisticalCorrector::StatisticalCorrectorStats stats
virtual void scHistoryUpdate(Addr branch_pc, const StaticInstPtr &inst, bool taken, BranchInfo *tage_bi, Addr corrTarget)
virtual void gUpdates(ThreadID tid, Addr pc, bool taken, BranchInfo *bi, int64_t phist)=0
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 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)
StatisticalCorrector(const StatisticalCorrectorParams &p)
virtual unsigned getIndUpd(Addr branch_pc) const
virtual unsigned getIndBias(Addr branch_pc, BranchInfo *bi, bool b) const
void ctrUpdate(T &ctr, bool taken, int nbits)
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 int gPredictions(ThreadID tid, Addr branch_pc, BranchInfo *bi, int &lsum, int64_t phist)=0
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, int64_t phist)
virtual int gIndexLogsSubstr(int nbr, int i)=0
int64_t gIndex(Addr branch_pc, int64_t bhist, int logs, int nbr, int i)
Statistics container.
Definition: group.hh:94
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition: group.hh:75
Bitfield< 7 > b
Definition: misc_types.hh:388
Bitfield< 7 > i
Definition: misc_types.hh:67
Bitfield< 24 > j
Definition: misc_types.hh:57
Bitfield< 30, 0 > index
Bitfield< 20, 16 > bi
Definition: types.hh:80
Bitfield< 6 > w
Definition: pagetable.hh:59
Bitfield< 54 > p
Definition: pagetable.hh:70
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
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
void updateLocalHistory(int ordinal, Addr branch_pc, bool taken, Addr extraXor=0)

Generated on Wed Dec 21 2022 10:22:31 for gem5 by doxygen 1.9.1