gem5 v24.0.0.0
Loading...
Searching...
No Matches
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
46namespace gem5
47{
48
49namespace 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
97
103
104void
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
133void
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
155unsigned
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
163unsigned
165{
166 return (((((branch_pc ^ (branch_pc >> (logBias-2)))<<1) ^
167 (bi->highConf))<<1) + bi->predBeforeSC) & ((1<<logBias) -1);
168}
169
170unsigned
172{
173 return ((branch_pc ^ (branch_pc >>2)) & ((1 << (logSizeUp)) - 1));
174}
175
176unsigned
178{
179 return ((branch_pc ^ (branch_pc >>2)) & ((1 << (logSizeUps)) - 1));
180}
181
182int64_t
183StatisticalCorrector::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
192int
193StatisticalCorrector::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
208void
209StatisticalCorrector::gUpdate(Addr branch_pc, bool taken, int64_t hist,
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
229bool
230StatisticalCorrector::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
294void
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)) {
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
323void
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))) {
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
382void
384{
385 if (taken == bi->scPred) {
386 stats.correct++;
387 } else {
388 stats.wrong++;
389 }
390}
391
392void
398
399size_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.
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)
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: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
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
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
void updateLocalHistory(int ordinal, Addr branch_pc, bool taken, Addr extraXor=0)

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