From 61a998093391b22761e3ecf2d4bb8e99515fb0ac Mon Sep 17 00:00:00 2001 From: Javier Bueno Hedo Date: Wed, 12 Jun 2019 15:42:19 +0200 Subject: [PATCH] cpu: Added the Multiperspective Perceptron Predictor with TAGE (8KB and 64KB) MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Described by the following article: Jiménez, D. "Multiperspective perceptron predictor with TAGE." Championship Branch Prediction (CBP-5) (2016). Change-Id: Ica3c121a4c94657d9015573085040e8a1984b069 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/19188 Tested-by: kokoro Maintainer: Andreas Sandberg Reviewed-by: Ilias Vougioukas --- src/cpu/pred/BranchPredictor.py | 194 +++++ src/cpu/pred/SConscript | 3 + src/cpu/pred/loop_predictor.cc | 9 + src/cpu/pred/loop_predictor.hh | 2 + src/cpu/pred/multiperspective_perceptron.cc | 37 +- src/cpu/pred/multiperspective_perceptron.hh | 12 +- .../pred/multiperspective_perceptron_tage.cc | 697 ++++++++++++++++++ .../pred/multiperspective_perceptron_tage.hh | 236 ++++++ .../multiperspective_perceptron_tage_64KB.cc | 230 ++++++ .../multiperspective_perceptron_tage_64KB.hh | 88 +++ .../multiperspective_perceptron_tage_8KB.cc | 196 +++++ .../multiperspective_perceptron_tage_8KB.hh | 84 +++ src/cpu/pred/statistical_corrector.cc | 58 +- src/cpu/pred/statistical_corrector.hh | 39 +- src/cpu/pred/tage_base.cc | 49 +- src/cpu/pred/tage_base.hh | 15 +- src/cpu/pred/tage_sc_l.cc | 9 +- src/cpu/pred/tage_sc_l.hh | 2 +- src/cpu/pred/tage_sc_l_64KB.cc | 9 +- src/cpu/pred/tage_sc_l_64KB.hh | 2 +- src/cpu/pred/tage_sc_l_8KB.cc | 11 +- src/cpu/pred/tage_sc_l_8KB.hh | 4 +- 22 files changed, 1909 insertions(+), 77 deletions(-) create mode 100644 src/cpu/pred/multiperspective_perceptron_tage.cc create mode 100644 src/cpu/pred/multiperspective_perceptron_tage.hh create mode 100644 src/cpu/pred/multiperspective_perceptron_tage_64KB.cc create mode 100644 src/cpu/pred/multiperspective_perceptron_tage_64KB.hh create mode 100644 src/cpu/pred/multiperspective_perceptron_tage_8KB.cc create mode 100644 src/cpu/pred/multiperspective_perceptron_tage_8KB.hh diff --git a/src/cpu/pred/BranchPredictor.py b/src/cpu/pred/BranchPredictor.py index 967489a16..119640553 100644 --- a/src/cpu/pred/BranchPredictor.py +++ b/src/cpu/pred/BranchPredictor.py @@ -133,6 +133,7 @@ class TAGEBase(SimObject): logUResetPeriod = Param.Unsigned(18, "Log period in number of branches to reset TAGE useful counters") numUseAltOnNa = Param.Unsigned(1, "Number of USE_ALT_ON_NA counters") + initialTCounterValue = Param.Int(1 << 17, "Initial value of tCounter") useAltOnNaBits = Param.Unsigned(4, "Size of the USE_ALT_ON_NA counter(s)") maxNumAlloc = Param.Unsigned(1, @@ -210,6 +211,7 @@ class TAGE_SC_L_TAGE(TAGEBase): pathHistBits = 27 maxNumAlloc = 2 logUResetPeriod = 10 + initialTCounterValue = 1 << 9 useAltOnNaBits = 5 # TODO No speculation implemented as of now speculativeHistUpdate = False @@ -334,14 +336,20 @@ class StatisticalCorrector(SimObject): bwnb = Param.Unsigned("Num global backward branch GEHL lengths") bwm = VectorParam.Int("Global backward branch GEHL lengths") logBwnb = Param.Unsigned("Log num of global backward branch GEHL entries") + bwWeightInitValue = Param.Int( + "Initial value of the weights of the global backward branch GEHL entries") lnb = Param.Unsigned("Num first local history GEHL lenghts") lm = VectorParam.Int("First local history GEHL lengths") logLnb = Param.Unsigned("Log number of first local history GEHL entries") + lWeightInitValue = Param.Int( + "Initial value of the weights of the first local history GEHL entries") inb = Param.Unsigned(1, "Num IMLI GEHL lenghts") im = VectorParam.Int([8], "IMLI history GEHL lengths") logInb = Param.Unsigned("Log number of IMLI GEHL entries") + iWeightInitValue = Param.Int( + "Initial value of the weights of the IMLI history GEHL entries") logBias = Param.Unsigned("Log size of Bias tables") @@ -362,6 +370,9 @@ class StatisticalCorrector(SimObject): scCountersWidth = Param.Unsigned(6, "Statistical corrector counters width") + initialUpdateThresholdValue = Param.Int(0, + "Initial pUpdate threshold counter value") + # TAGE-SC-L branch predictor as desribed in # https://www.jilp.org/cbp2016/paper/AndreSeznecLimited.pdf # It is a modified LTAGE predictor plus a statistical corrector predictor @@ -425,12 +436,15 @@ class TAGE_SC_L_64KB_StatisticalCorrector(StatisticalCorrector): bwnb = 3 bwm = [40, 24, 10] logBwnb = 10 + bwWeightInitValue = 7 lnb = 3 lm = [11, 6, 3] logLnb = 10 + lWeightInitValue = 7 logInb = 8 + iWeightInitValue = 7 class TAGE_SC_L_8KB_StatisticalCorrector(StatisticalCorrector): type = 'TAGE_SC_L_8KB_StatisticalCorrector' @@ -447,12 +461,15 @@ class TAGE_SC_L_8KB_StatisticalCorrector(StatisticalCorrector): bwnb = 2 logBwnb = 7 bwm = [16, 8] + bwWeightInitValue = 7 lnb = 2 logLnb = 7 lm = [6, 3] + lWeightInitValue = 7 logInb = 7 + iWeightInitValue = 7 # 64KB TAGE-SC-L branch predictor as described in # http://www.jilp.org/cbp2016/paper/AndreSeznecLimited.pdf @@ -536,6 +553,9 @@ class MultiperspectivePerceptron(BranchPredictor): speculative_update = Param.Bool(False, "Use speculative update for histories") + initial_ghist_length = Param.Int(1, "Initial GHist length value") + ignore_path_size = Param.Bool(False, "Ignore the path storage") + class MultiperspectivePerceptron8KB(MultiperspectivePerceptron): type = 'MultiperspectivePerceptron8KB' cxx_class = 'MultiperspectivePerceptron8KB' @@ -557,3 +577,177 @@ class MultiperspectivePerceptron64KB(MultiperspectivePerceptron): imli_mask1 = 0xc1000 imli_mask4 = 0x80008000 recencypos_mask = 0x100000090 + +class MPP_TAGE(TAGEBase): + type = 'MPP_TAGE' + cxx_class = 'MPP_TAGE' + cxx_header = 'cpu/pred/multiperspective_perceptron_tage.hh' + nHistoryTables = 15 + pathHistBits = 27 + instShiftAmt = 0 + histBufferSize = 16384 + maxHist = 4096; + tagTableTagWidths = [0, 7, 9, 9, 9, 10, 11, 11, 12, 12, + 12, 13, 14, 15, 15, 15] + logTagTableSizes = [14, 10, 11, 11, 11, 11, 11, 12, 12, + 10, 11, 11, 9, 7, 7, 8] + tunedHistoryLengths = VectorParam.Unsigned([0, 5, 12, 15, 21, 31, 43, 64, + 93, 137, 200, 292, 424, 612, 877, 1241], "Tuned history lengths") + + logUResetPeriod = 10 + initialTCounterValue = 0 + numUseAltOnNa = 512 + speculativeHistUpdate = False + +class MPP_LoopPredictor(LoopPredictor): + type = 'MPP_LoopPredictor' + cxx_class = 'MPP_LoopPredictor' + cxx_header = 'cpu/pred/multiperspective_perceptron_tage.hh' + useDirectionBit = True + useHashing = True + useSpeculation = False + loopTableConfidenceBits = 4 + loopTableAgeBits = 4 + initialLoopAge = 7 + initialLoopIter = 0 + loopTableIterBits = 12 + optionalAgeReset = False + restrictAllocation = True + logSizeLoopPred = 6 + loopTableTagBits = 10 + +class MPP_StatisticalCorrector(StatisticalCorrector): + type = 'MPP_StatisticalCorrector' + cxx_class = 'MPP_StatisticalCorrector' + cxx_header = 'cpu/pred/multiperspective_perceptron_tage.hh' + abstract = True + + # Unused in this Statistical Corrector + bwnb = 0 + bwm = [ ] + logBwnb = 0 + bwWeightInitValue = -1 + + # Unused in this Statistical Corrector + logInb = 0 + iWeightInitValue = -1 + + extraWeightsWidth = 0 + pUpdateThresholdWidth = 10 + initialUpdateThresholdValue = 35 + logSizeUp = 5 + + lnb = 3 + lm = [11, 6, 3] + logLnb = 10 + lWeightInitValue = -1 + + gnb = Param.Unsigned(4, "Num global branch GEHL lengths") + gm = VectorParam.Int([27, 22, 17, 14], "Global branch GEHL lengths") + logGnb = Param.Unsigned(10, "Log number of global branch GEHL entries") + + pnb = Param.Unsigned(4, "Num variation global branch GEHL lengths") + pm = VectorParam.Int([16, 11, 6, 3], + "Variation global branch GEHL lengths") + logPnb = Param.Unsigned(9, + "Log number of variation global branch GEHL entries") + +class MultiperspectivePerceptronTAGE(MultiperspectivePerceptron): + type = 'MultiperspectivePerceptronTAGE' + cxx_class = 'MultiperspectivePerceptronTAGE' + cxx_header = 'cpu/pred/multiperspective_perceptron_tage.hh' + abstract = True + instShiftAmt = 4 + + imli_mask1 = 0x70 + imli_mask4 = 0 + num_filter_entries = 0 + num_local_histories = 0 + recencypos_mask = 0 # Unused + threshold = -1 + initial_ghist_length = 0 + ignore_path_size = True + n_sign_bits = 1; + + tage = Param.TAGEBase("Tage object") + loop_predictor = Param.LoopPredictor("Loop predictor") + statistical_corrector = Param.StatisticalCorrector("Statistical Corrector") + +class MPP_StatisticalCorrector_64KB(MPP_StatisticalCorrector): + type = 'MPP_StatisticalCorrector_64KB' + cxx_class = 'MPP_StatisticalCorrector_64KB' + cxx_header = 'cpu/pred/multiperspective_perceptron_tage_64KB.hh' + + logBias = 8 + + snb = Param.Unsigned(4, "Num second local history GEHL lenghts") + sm = VectorParam.Int([16, 11, 6, 3], "Second local history GEHL lengths") + logSnb = Param.Unsigned(9, + "Log number of second local history GEHL entries") + + tnb = Param.Unsigned(3, "Num third local history GEHL lenghts") + tm = VectorParam.Int([22, 17, 14], "Third local history GEHL lengths") + logTnb = Param.Unsigned(9, + "Log number of third local history GEHL entries") + + numEntriesSecondLocalHistories = Param.Unsigned(16, + "Number of entries for second local histories") + numEntriesThirdLocalHistories = Param.Unsigned(16, + "Number of entries for second local histories") + + numEntriesFirstLocalHistories = 256 + +class MultiperspectivePerceptronTAGE64KB(MultiperspectivePerceptronTAGE): + type = 'MultiperspectivePerceptronTAGE64KB' + cxx_class = 'MultiperspectivePerceptronTAGE64KB' + cxx_header = 'cpu/pred/multiperspective_perceptron_tage_64KB.hh' + + budgetbits = 65536 * 8 + 2048 + + tage = MPP_TAGE() + loop_predictor = MPP_LoopPredictor() + statistical_corrector = MPP_StatisticalCorrector_64KB() + +class MPP_TAGE_8KB(MPP_TAGE): + type = 'MPP_TAGE_8KB' + cxx_class = 'MPP_TAGE_8KB' + cxx_header = 'cpu/pred/multiperspective_perceptron_tage_8KB.hh' + nHistoryTables = 10 + tagTableTagWidths = [0, 7, 7, 7, 8, 9, 10, 10, 11, 13, 13] + logTagTableSizes = [12, 8, 8, 9, 9, 8, 8, 8, 7, 6, 7] + tunedHistoryLengths = [0, 4, 8, 13, 23, 36, 56, 93, 145, 226, 359] + +class MPP_LoopPredictor_8KB(MPP_LoopPredictor): + type = 'MPP_LoopPredictor_8KB' + cxx_class = 'MPP_LoopPredictor_8KB' + cxx_header = 'cpu/pred/multiperspective_perceptron_tage_8KB.hh' + loopTableIterBits = 10 + logSizeLoopPred = 4 + +class MPP_StatisticalCorrector_8KB(MPP_StatisticalCorrector): + type = 'MPP_StatisticalCorrector_8KB' + cxx_class = 'MPP_StatisticalCorrector_8KB' + cxx_header = 'cpu/pred/multiperspective_perceptron_tage_8KB.hh' + + logBias = 7 + + lnb = 2 + lm = [8, 3] + logLnb = 9 + + logGnb = 9 + + logPnb = 7 + + numEntriesFirstLocalHistories = 64 + +class MultiperspectivePerceptronTAGE8KB(MultiperspectivePerceptronTAGE): + type = 'MultiperspectivePerceptronTAGE8KB' + cxx_class = 'MultiperspectivePerceptronTAGE8KB' + cxx_header = 'cpu/pred/multiperspective_perceptron_tage_8KB.hh' + + budgetbits = 8192 * 8 + 2048 + + tage = MPP_TAGE_8KB() + loop_predictor = MPP_LoopPredictor_8KB() + statistical_corrector = MPP_StatisticalCorrector_8KB() diff --git a/src/cpu/pred/SConscript b/src/cpu/pred/SConscript index 27821a4aa..9775d4c6c 100644 --- a/src/cpu/pred/SConscript +++ b/src/cpu/pred/SConscript @@ -51,6 +51,9 @@ Source('ltage.cc') Source('multiperspective_perceptron.cc') Source('multiperspective_perceptron_8KB.cc') Source('multiperspective_perceptron_64KB.cc') +Source('multiperspective_perceptron_tage.cc') +Source('multiperspective_perceptron_tage_8KB.cc') +Source('multiperspective_perceptron_tage_64KB.cc') Source('statistical_corrector.cc') Source('tage_sc_l.cc') Source('tage_sc_l_8KB.cc') diff --git a/src/cpu/pred/loop_predictor.cc b/src/cpu/pred/loop_predictor.cc index bd32e41c8..abcaac409 100644 --- a/src/cpu/pred/loop_predictor.cc +++ b/src/cpu/pred/loop_predictor.cc @@ -360,6 +360,15 @@ LoopPredictor::regStats() "the prediction is wrong"); } +size_t +LoopPredictor::getSizeInBits() const +{ + return (1ULL << logSizeLoopPred) * + ((useSpeculation ? 3 : 2) * loopTableIterBits + + loopTableConfidenceBits + loopTableTagBits + + loopTableAgeBits + useDirectionBit); +} + LoopPredictor * LoopPredictorParams::create() { diff --git a/src/cpu/pred/loop_predictor.hh b/src/cpu/pred/loop_predictor.hh index bc626980c..5706c4532 100644 --- a/src/cpu/pred/loop_predictor.hh +++ b/src/cpu/pred/loop_predictor.hh @@ -259,5 +259,7 @@ class LoopPredictor : public SimObject void regStats() override; LoopPredictor(LoopPredictorParams *p); + + size_t getSizeInBits() const; }; #endif//__CPU_PRED_LOOP_PREDICTOR_HH__ diff --git a/src/cpu/pred/multiperspective_perceptron.cc b/src/cpu/pred/multiperspective_perceptron.cc index 47bbb0212..d081b493c 100644 --- a/src/cpu/pred/multiperspective_perceptron.cc +++ b/src/cpu/pred/multiperspective_perceptron.cc @@ -38,6 +38,7 @@ #include "cpu/pred/multiperspective_perceptron.hh" +#include "base/random.hh" #include "debug/Branch.hh" int @@ -121,14 +122,20 @@ MultiperspectivePerceptron::MultiperspectivePerceptron( tuneonly(p->tuneonly), extra_rounds(p->extra_rounds), speed(p->speed), budgetbits(p->budgetbits), speculative_update(p->speculative_update), threadData(p->numThreads, nullptr), doing_local(false), - doing_recency(false), assoc(0), ghist_length(1), modghist_length(1), - path_length(1), randSeed(0xdeadbeef), thresholdCounter(0), - theta(p->initial_theta), imli_counter_bits(4), modhist_indices(), - modhist_lengths(), modpath_indices(), modpath_lengths() + doing_recency(false), assoc(0), ghist_length(p->initial_ghist_length), + modghist_length(1), path_length(1), thresholdCounter(0), + theta(p->initial_theta), extrabits(0), imli_counter_bits(4), + modhist_indices(), modhist_lengths(), modpath_indices(), modpath_lengths() { fatal_if(speculative_update, "Speculative update not implemented"); } +void +MultiperspectivePerceptron::setExtraBits(int bits) +{ + extrabits = bits; +} + void MultiperspectivePerceptron::init() { @@ -147,7 +154,7 @@ MultiperspectivePerceptron::init() static_cast(params()); computeBits(p->num_filter_entries, p->num_local_histories, - p->local_history_length); + p->local_history_length, p->ignore_path_size); for (int i = 0; i < threadData.size(); i += 1) { threadData[i] = new ThreadData(p->num_filter_entries, @@ -163,19 +170,24 @@ MultiperspectivePerceptron::init() void MultiperspectivePerceptron::computeBits(int num_filter_entries, - int nlocal_histories, int local_history_length) { - int totalbits = 0; + int nlocal_histories, int local_history_length, bool ignore_path_size) +{ + int totalbits = extrabits; for (auto &imli_bits : imli_counter_bits) { totalbits += imli_bits; } totalbits += ghist_length; - totalbits += path_length * 16; + if (!ignore_path_size) { + totalbits += path_length * 16; + } totalbits += (threshold >= 0) ? (tunebits * specs.size()) : 0; for (auto &len : modhist_lengths) { totalbits += len; } - for (auto &len : modpath_lengths) { - totalbits += 16 * len; + if (!ignore_path_size) { + for (auto &len : modpath_lengths) { + totalbits += 16 * len; + } } totalbits += doing_local ? (nlocal_histories * local_history_length) : 0; totalbits += doing_recency ? (assoc * 16) : 0; @@ -482,7 +494,7 @@ MultiperspectivePerceptron::train(ThreadID tid, MPPBranchInfo &bi, bool taken) do { // udpate a random weight int besti = -1; - int nrand = rand_r(&randSeed) % specs.size(); + int nrand = random_mt.random() % specs.size(); int pout; found = false; for (int j = 0; j < specs.size(); j += 1) { @@ -645,7 +657,8 @@ MultiperspectivePerceptron::update(ThreadID tid, Addr instPC, bool taken, // filter, blow a random filter entry away if (decay && transition && ((threadData[tid]->occupancy > decay) || (decay == 1))) { - int rnd = rand_r(&randSeed) % threadData[tid]->filterTable.size(); + int rnd = random_mt.random() % + threadData[tid]->filterTable.size(); FilterEntry &frand = threadData[tid]->filterTable[rnd]; if (frand.seenTaken && frand.seenUntaken) { threadData[tid]->occupancy -= 1; diff --git a/src/cpu/pred/multiperspective_perceptron.hh b/src/cpu/pred/multiperspective_perceptron.hh index e81bd8eec..9d4503244 100644 --- a/src/cpu/pred/multiperspective_perceptron.hh +++ b/src/cpu/pred/multiperspective_perceptron.hh @@ -358,9 +358,9 @@ class MultiperspectivePerceptron : public BPredUnit int ghist_length; int modghist_length; int path_length; - unsigned int randSeed; int thresholdCounter; int theta; + int extrabits; std::vector imli_counter_bits; std::vector modhist_indices; std::vector modhist_lengths; @@ -416,9 +416,10 @@ class MultiperspectivePerceptron : public BPredUnit * @param num_filter_entries number of entries of the filter * @param nlocal_histories number of local history entries * @param local_history_length size of each local history entry + * @param ignore_path_size ignore the path length storage */ void computeBits(int num_filter_entries, int nlocal_histories, - int local_history_length); + int local_history_length, bool ignore_path_size); /** * Creates the tables of the predictor @@ -1013,6 +1014,13 @@ class MultiperspectivePerceptron : public BPredUnit public: MultiperspectivePerceptron(const MultiperspectivePerceptronParams *params); + /** + * Sets the starting number of storage bits to compute the number of + * table entries + * @param bits number of bits used + */ + void setExtraBits(int bits); + void init() override; void uncondBranch(ThreadID tid, Addr pc, void * &bp_history) override; diff --git a/src/cpu/pred/multiperspective_perceptron_tage.cc b/src/cpu/pred/multiperspective_perceptron_tage.cc new file mode 100644 index 000000000..3ef5f4f39 --- /dev/null +++ b/src/cpu/pred/multiperspective_perceptron_tage.cc @@ -0,0 +1,697 @@ +/* + * Copyright 2019 Texas A&M University + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Author: Daniel A. Jiménez + * Adapted to gem5 by: Javier Bueno Hedo + * + */ + +/* + * Multiperspective Perceptron Predictor with TAGE (by Daniel A. Jiménez) + */ + +#include "cpu/pred/multiperspective_perceptron_tage.hh" + +#include "base/random.hh" + +void +MPP_TAGE::calculateParameters() +{ + assert(tunedHistoryLengths.size() == (nHistoryTables+1)); + for (int i = 0; i <= nHistoryTables; i += 1) { + histLengths[i] = tunedHistoryLengths[i]; + } +} + +void +MPP_TAGE::handleTAGEUpdate(Addr branch_pc, bool taken, + TAGEBase::BranchInfo* bi) +{ + if (bi->hitBank > 0) { + if (abs (2 * gtable[bi->hitBank][bi->hitBankIndex].ctr + 1) == 1) { + if (bi->longestMatchPred != taken) { + // acts as a protection + if (bi->altBank > 0) { + ctrUpdate(gtable[bi->altBank][bi->altBankIndex].ctr, taken, + tagTableCounterBits); + } + if (bi->altBank == 0){ + baseUpdate(branch_pc, taken, bi); + } + } + } + + ctrUpdate(gtable[bi->hitBank][bi->hitBankIndex].ctr, taken, + tagTableCounterBits); + + //sign changes: no way it can have been useful + if (abs (2 * gtable[bi->hitBank][bi->hitBankIndex].ctr + 1) == 1) { + gtable[bi->hitBank][bi->hitBankIndex].u = 0; + } + } else { + baseUpdate(branch_pc, taken, bi); + } + + if ((bi->longestMatchPred != bi->altTaken) && + (bi->longestMatchPred == taken) && + (gtable[bi->hitBank][bi->hitBankIndex].u < (1 << tagTableUBits) -1)) { + gtable[bi->hitBank][bi->hitBankIndex].u++; + } +} + +void +MPP_TAGE::handleAllocAndUReset(bool alloc, bool taken, + TAGEBase::BranchInfo* bi, int nrand) +{ + if (!alloc) { + return; + } + + int a = 1; + + if ((random_mt.random() & 127) < 32) { + a = 2; + } + int dep = bi->hitBank + a; + + int penalty = 0; + int numAllocated = 0; + int T = 1; + + for (int i = dep; i <= nHistoryTables; i += 1) { + if (noSkip[i]) { + if (gtable[i][bi->tableIndices[i]].u == 0) { + gtable[i][bi->tableIndices[i]].tag = bi->tableTags[i]; + gtable[i][bi->tableIndices[i]].ctr = taken ? 0 : -1; + numAllocated++; + if (T <= 0) { + break; + } + i += 1; + T -= 1; + } else { + penalty++; + } + } else { assert(false); } + } + + tCounter += (penalty - numAllocated); + + handleUReset(); +} + +void +MPP_TAGE::handleUReset() +{ + //just the best formula for the Championship: + //In practice when one out of two entries are useful + if (tCounter < 0) { + tCounter = 0; + } + + if (tCounter >= ((ULL(1) << logUResetPeriod))) { + // Update the u bits for the short tags table + for (int i = 1; i <= nHistoryTables; i++) { + for (int j = 0; j < (ULL(1) << logTagTableSizes[i]); j++) { + resetUctr(gtable[i][j].u); + } + } + + tCounter = 0; + } +} + +void +MPP_TAGE::resetUctr(uint8_t &u) +{ + // On real HW it should be u >>= 1 instead of if > 0 then u-- + if (u > 0) { + u--; + } +} + + +int +MPP_TAGE::bindex(Addr pc_in) const +{ + uint32_t pc = (uint32_t) pc_in; + return ((pc ^ (pc >> 4)) & + ((ULL(1) << (logTagTableSizes[0])) - 1)); +} + +unsigned +MPP_TAGE::getUseAltIdx(TAGEBase::BranchInfo* bi, Addr branch_pc) +{ + uint32_t hpc = ((uint32_t) branch_pc); + hpc = (hpc ^(hpc >> 4)); + return 2 * ((hpc & ((numUseAltOnNa/2)-1)) ^ bi->longestMatchPred) + + ((bi->hitBank > (nHistoryTables / 3)) ? 1 : 0); +} + +void +MPP_TAGE::adjustAlloc(bool & alloc, bool taken, bool pred_taken) +{ + // Do not allocate too often if the prediction is ok + if ((taken == pred_taken) && ((random_mt.random() & 31) != 0)) { + alloc = false; + } +} + +void +MPP_TAGE::updateHistories( + ThreadID tid, Addr branch_pc, bool taken, TAGEBase::BranchInfo* b, + bool speculative, const StaticInstPtr &inst, Addr target) +{ + if (speculative != speculativeHistUpdate) { + return; + } + // speculation is not implemented + assert(! speculative); + + ThreadHistory& tHist = threadHistory[tid]; + + int brtype = inst->isDirectCtrl() ? 0 : 2; + if (! inst->isUncondCtrl()) { + ++brtype; + } + updatePathAndGlobalHistory(tHist, brtype, taken, branch_pc, target); +} + +void +MPP_TAGE::updatePathAndGlobalHistory( + ThreadHistory& tHist, int brtype, bool taken, Addr branch_pc, Addr target) +{ + // TAGE update + int tmp = (branch_pc << 1) + taken; + int path = branch_pc; + + int maxt = (brtype & 1) ? 1 : 4; + + for (int t = 0; t < maxt; t++) { + bool dir = (tmp & 1); + tmp >>= 1; + int pathbit = (path & 127); + path >>= 1; + updateGHist(tHist.gHist, dir, tHist.globalHistory, tHist.ptGhist); + tHist.pathHist = (tHist.pathHist << 1) ^ pathbit; + for (int i = 1; i <= nHistoryTables; i++) { + tHist.computeIndices[i].update(tHist.gHist); + tHist.computeTags[0][i].update(tHist.gHist); + tHist.computeTags[1][i].update(tHist.gHist); + } + } +} + +bool +MPP_TAGE::isHighConfidence(TAGEBase::BranchInfo *bi) const +{ + if (bi->hitBank > 0) { + return (abs(2 * gtable[bi->hitBank][bi->hitBankIndex].ctr + 1)) >= + ((1 << tagTableCounterBits) - 1); + } else { + int bim = (btablePrediction[bi->bimodalIndex] << 1) + + btableHysteresis[bi->bimodalIndex >> logRatioBiModalHystEntries]; + return (bim == 0) || (bim == 3); + } + +} + +MPP_TAGE* +MPP_TAGEParams::create() +{ + return new MPP_TAGE(this); +} + +bool +MPP_LoopPredictor::calcConf(int index) const +{ + return LoopPredictor::calcConf(index) || + (ltable[index].confidence * ltable[index].numIter > 128); +} + +bool +MPP_LoopPredictor::optionalAgeInc() const +{ + return ((random_mt.random() & 7) == 0); +} + +MPP_LoopPredictor* +MPP_LoopPredictorParams::create() +{ + return new MPP_LoopPredictor(this); +} + +MPP_StatisticalCorrector::MPP_StatisticalCorrector( + const MPP_StatisticalCorrectorParams *p) : StatisticalCorrector(p), + thirdH(0), pnb(p->pnb), logPnb(p->logPnb), pm(p->pm), gnb(p->gnb), + logGnb(p->logGnb), gm(p->gm) +{ + initGEHLTable(pnb, pm, pgehl, logPnb, wp, -1); + initGEHLTable(gnb, gm, ggehl, logGnb, wg, -1); + + for (int8_t &pos : wl) { + pos = -1; + } +} + +void +MPP_StatisticalCorrector::initBias() +{ + for (int j = 0; j < (1 << logBias); j++) { + if (j & 1) { + bias[j] = 15; + biasSK[j] = 15; + } else { + bias[j] = -16; + biasSK[j] = -16; + } + } +} + +unsigned +MPP_StatisticalCorrector::getIndBias(Addr branch_pc, + StatisticalCorrector::BranchInfo* bi, bool bias) const +{ + unsigned int truncated_pc = branch_pc; + return ((truncated_pc << 1) + bi->predBeforeSC) & ((1 << logBias) - 1); +} + +unsigned +MPP_StatisticalCorrector::getIndBiasSK(Addr branch_pc, + StatisticalCorrector::BranchInfo* bi) const +{ + return (((branch_pc ^ (branch_pc >> (logBias - 1))) << 1) + + bi->predBeforeSC) & ((1 << logBias) - 1); +} + +unsigned +MPP_StatisticalCorrector::getIndBiasBank(Addr branch_pc, + StatisticalCorrector::BranchInfo* bi, int hitBank, int altBank) const +{ + return 0; +} + +int +MPP_StatisticalCorrector::gIndexLogsSubstr(int nbr, int i) +{ + return (i >= (nbr - 2)) ? 1 : 0; +} + +unsigned +MPP_StatisticalCorrector::getIndUpd(Addr branch_pc) const +{ + return ((branch_pc ^ (branch_pc >> 4)) & ((1 << (logSizeUp)) - 1)); +} + +void +MPP_StatisticalCorrector::gUpdate(Addr branch_pc, bool taken, int64_t hist, + std::vector & length, std::vector * tab, + int nbr, int logs, std::vector & w, + StatisticalCorrector::BranchInfo* bi) +{ + int percsum = 0; + for (int i = 0; i < nbr; i++) { + int64_t bhist = hist & ((int64_t) ((1 << length[i]) - 1)); + int64_t index = gIndex(branch_pc, bhist, logs, nbr, i); + percsum += (2 * tab[i][index] + 1); + ctrUpdate(tab[i][index], taken, scCountersWidth - (i < (nbr - 1))); + } +} + +bool +MPP_StatisticalCorrector::scPredict(ThreadID tid, Addr branch_pc, + bool cond_branch, StatisticalCorrector::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) +{ + bool pred_taken = prev_pred_taken; + if (cond_branch) { + + bi->predBeforeSC = prev_pred_taken; + + int lsum = init_lsum; + + getBiasLSUM(branch_pc, bi, lsum); + + int thres = gPredictions(tid, branch_pc, bi, lsum, phist); + + // These will be needed at update time + bi->lsum = lsum; + bi->thres = thres; + bi->scPred = (lsum >= 0); + + if (pred_taken != bi->scPred) { + pred_taken = bi->scPred; + + if (bi->highConf /* comes from tage prediction */) { + if ((abs(lsum) < thres / 3)) + pred_taken = (firstH < 0) ? bi->scPred : prev_pred_taken; + else if ((abs(lsum) < 2 * thres / 3)) + pred_taken = (secondH < 0) ? bi->scPred : prev_pred_taken; + else if ((abs(lsum) < thres)) + pred_taken = (thirdH < 0) ? bi->scPred : prev_pred_taken; + } + } + } + + return pred_taken; +} + +MultiperspectivePerceptronTAGE::MultiperspectivePerceptronTAGE( + const MultiperspectivePerceptronTAGEParams *p) + : MultiperspectivePerceptron(p), tage(p->tage), + loopPredictor(p->loop_predictor), + statisticalCorrector(p->statistical_corrector) +{ + fatal_if(tage->isSpeculativeUpdateEnabled(), + "Speculative updates support is not implemented"); +} + +void +MultiperspectivePerceptronTAGE::init() +{ + tage->init(); + int numBitsTage = tage->getSizeInBits(); + int numBitsLoopPred = loopPredictor->getSizeInBits(); + int numBitsStatisticalCorrector = statisticalCorrector->getSizeInBits(); + + setExtraBits(numBitsTage + numBitsLoopPred + numBitsStatisticalCorrector); + MultiperspectivePerceptron::init(); +} + + +unsigned int +MultiperspectivePerceptronTAGE::getIndex(ThreadID tid, MPPTAGEBranchInfo &bi, + const HistorySpec &spec, int index) const +{ + // get the hash for the feature + unsigned int g = spec.getHash(tid, bi.getPC(), bi.getPC() >> 2, index); + // shift it and xor it with the hashed PC + unsigned long long int h = g; + h <<= 20; + h ^= (bi.getPC() ^ (bi.getPC() >> 2)); + + // maybe xor in an IMLI counter + if ((1ull << index) & imli_mask1) { + h += threadData[tid]->imli_counter[0]; + } + if ((1ull << index) & imli_mask4) { + h += threadData[tid]->imli_counter[3]; + } + + // return it modulo the table size + return h % table_sizes[index]; +} + + +int +MultiperspectivePerceptronTAGE::computePartialSum(ThreadID tid, + MPPTAGEBranchInfo &bi) const +{ + int yout = 0; + for (int i = 0; i < specs.size(); i += 1) { + yout += specs[i]->coeff * + threadData[tid]->tables[i][getIndex(tid, bi, *specs[i], i)]; + } + return yout; +} + +void +MultiperspectivePerceptronTAGE::updatePartial(ThreadID tid, + MPPTAGEBranchInfo &bi, + bool taken) +{ + // update tables + for (int i = 0; i < specs.size(); i += 1) { + unsigned int idx = getIndex(tid, bi, *specs[i], i); + short int *c = + &threadData[tid]->tables[i][idx]; + short int max_weight = (1 << (specs[i]->width - 1)) - 1; + short int min_weight = -(1 << (specs[i]->width - 1)); + if (taken) { + if (*c < max_weight) { + *c += 1; + } + } else { + if (*c > min_weight) { + *c -= 1; + } + } + } +} + +void +MultiperspectivePerceptronTAGE::updateHistories(ThreadID tid, + MPPTAGEBranchInfo &bi, + bool taken) +{ + unsigned int hpc = (bi.getPC() ^ (bi.getPC() >> 2)); + unsigned int pc = bi.getPC(); + + // update recency stack + unsigned short recency_pc = pc >> 2; + threadData[tid]->insertRecency(recency_pc, assoc); + + // update acyclic history + threadData[tid]->updateAcyclic(taken, hpc); + + // update modpath histories + for (int ii = 0; ii < modpath_indices.size(); ii +=1) { + int i = modpath_indices[ii]; + if (hpc % (i + 2) == 0) { + memmove(&threadData[tid]->modpath_histories[i][1], + &threadData[tid]->modpath_histories[i][0], + sizeof(unsigned short int) * (modpath_lengths[ii] - 1)); + threadData[tid]->modpath_histories[i][0] = hpc; + } + } + + // update modulo histories + for (int ii = 0; ii < modhist_indices.size(); ii += 1) { + int i = modhist_indices[ii]; + if (hpc % (i + 2) == 0) { + for (int j = modhist_lengths[ii] - 1; j > 0; j -= 1) { + threadData[tid]->mod_histories[i][j] = + threadData[tid]->mod_histories[i][j-1]; + } + threadData[tid]->mod_histories[i][0] = taken; + } + } + + // update blurry history + std::vector> &blurrypath_histories = + threadData[tid]->blurrypath_histories; + for (int i = 0; i < blurrypath_histories.size(); i += 1) + { + if (blurrypath_histories[i].size() > 0) { + unsigned int z = pc >> i; + if (blurrypath_histories[i][0] != z) { + memmove(&blurrypath_histories[i][1], + &blurrypath_histories[i][0], + sizeof(unsigned int) * + (blurrypath_histories[i].size() - 1)); + blurrypath_histories[i][0] = z; + } + } + } +} + +bool +MultiperspectivePerceptronTAGE::lookup(ThreadID tid, Addr instPC, + void * &bp_history) +{ + MPPTAGEBranchInfo *bi = + new MPPTAGEBranchInfo(instPC, pcshift, true, *tage, *loopPredictor, + *statisticalCorrector); + bp_history = (void *)bi; + bool pred_taken = tage->tagePredict(tid, instPC, true, bi->tageBranchInfo); + + pred_taken = loopPredictor->loopPredict(tid, instPC, true, + bi->lpBranchInfo, pred_taken, instShiftAmt); + + bi->scBranchInfo->highConf = tage->isHighConfidence(bi->tageBranchInfo); + + int init_lsum = 22; + if (!pred_taken) { + init_lsum = -init_lsum; + } + init_lsum += computePartialSum(tid, *bi); + + pred_taken = statisticalCorrector->scPredict(tid, instPC, true, + bi->scBranchInfo, pred_taken, false /* bias_bit: unused */, + false /* use_tage_ctr: unused */, 0 /* conf_ctr: unused */, + 0 /* conf_bits: unused */, 0 /* hitBank: unused */, + 0 /* altBank: unused */, tage->getPathHist(tid), init_lsum); + bi->predictedTaken = pred_taken; + bi->lpBranchInfo->predTaken = pred_taken; + return pred_taken; +} + + +void +MPP_StatisticalCorrector::condBranchUpdate(ThreadID tid, Addr branch_pc, + bool taken, StatisticalCorrector::BranchInfo *bi, Addr corrTarget, + bool bias_bit, int hitBank, int altBank, int64_t phist) +{ + bool scPred = (bi->lsum >= 0); + + if (bi->predBeforeSC != scPred) { + if (abs(bi->lsum) < bi->thres) { + if (bi->highConf) { + if (abs(bi->lsum) < bi->thres / 3) { + ctrUpdate(firstH, (bi->predBeforeSC == taken), + chooserConfWidth); + } else if (abs(bi->lsum) < 2 * bi->thres / 3) { + ctrUpdate(secondH, (bi->predBeforeSC == taken), + chooserConfWidth); + } else if (abs(bi->lsum) < bi->thres) { + ctrUpdate(thirdH, (bi->predBeforeSC == taken), + chooserConfWidth); + } + } + } + } + + if ((scPred != taken) || ((abs(bi->lsum) < bi->thres))) { + + ctrUpdate(pUpdateThreshold[getIndUpd(branch_pc)], (scPred != taken), + pUpdateThresholdWidth + 1); //+1 because the sign is ignored + if (pUpdateThreshold[getIndUpd(branch_pc)] < 0) + pUpdateThreshold[getIndUpd(branch_pc)] = 0; + + unsigned indBias = getIndBias(branch_pc, bi, false); + unsigned indBiasSK = getIndBiasSK(branch_pc, bi); + + ctrUpdate(bias[indBias], taken, scCountersWidth); + ctrUpdate(biasSK[indBiasSK], taken, scCountersWidth); + + gUpdates(tid, branch_pc, taken, bi, phist); + } +} + +void +MultiperspectivePerceptronTAGE::update(ThreadID tid, Addr instPC, bool taken, + void *bp_history, bool squashed, + const StaticInstPtr & inst, + Addr corrTarget) +{ + assert(bp_history); + MPPTAGEBranchInfo *bi = static_cast(bp_history); + + assert(corrTarget != MaxAddr); + + if (squashed) { + if (tage->isSpeculativeUpdateEnabled()) { + // This restores the global history, then update it + // and recomputes the folded histories. + tage->squash(tid, taken, bi->tageBranchInfo, corrTarget); + if (bi->tageBranchInfo->condBranch) { + loopPredictor->squashLoop(bi->lpBranchInfo); + } + } + return; + } + + if (bi->isUnconditional()) { + statisticalCorrector->scHistoryUpdate(instPC, inst, taken, + bi->scBranchInfo, corrTarget); + tage->updateHistories(tid, instPC, taken, bi->tageBranchInfo, false, + inst, corrTarget); + } else { + tage->updateStats(taken, bi->tageBranchInfo); + loopPredictor->updateStats(taken, bi->lpBranchInfo); + statisticalCorrector->updateStats(taken, bi->scBranchInfo); + + loopPredictor->condBranchUpdate(tid, instPC, taken, + bi->tageBranchInfo->tagePred, bi->lpBranchInfo, instShiftAmt); + + bool scPred = (bi->scBranchInfo->lsum >= 0); + if ((scPred != taken) || + ((abs(bi->scBranchInfo->lsum) < bi->scBranchInfo->thres))) { + updatePartial(tid, *bi, taken); + } + statisticalCorrector->condBranchUpdate(tid, instPC, taken, + bi->scBranchInfo, corrTarget, false /* bias_bit: unused */, + 0 /* hitBank: unused */, 0 /* altBank: unused*/, + tage->getPathHist(tid)); + + tage->condBranchUpdate(tid, instPC, taken, bi->tageBranchInfo, + random_mt.random(), corrTarget, + bi->predictedTaken, true); + + updateHistories(tid, *bi, taken); + + if (!tage->isSpeculativeUpdateEnabled()) { + if (inst->isCondCtrl() && inst->isDirectCtrl() + && !inst->isCall() && !inst->isReturn()) { + uint32_t truncated_target = corrTarget; + uint32_t truncated_pc = instPC; + if (truncated_target < truncated_pc) { + if (!taken) { + threadData[tid]->imli_counter[0] = 0; + } else { + threadData[tid]->imli_counter[0] += 1; + } + } else { + if (taken) { + threadData[tid]->imli_counter[3] = 0; + } else { + threadData[tid]->imli_counter[3] += 1; + } + } + } + + statisticalCorrector->scHistoryUpdate(instPC, inst, taken, + bi->scBranchInfo, corrTarget); + + tage->updateHistories(tid, instPC, taken, bi->tageBranchInfo, + false, inst, corrTarget); + } + } + delete bi; +} + +void +MultiperspectivePerceptronTAGE::uncondBranch(ThreadID tid, Addr pc, + void * &bp_history) +{ + MPPTAGEBranchInfo *bi = + new MPPTAGEBranchInfo(pc, pcshift, false, *tage, *loopPredictor, + *statisticalCorrector); + bp_history = (void *) bi; +} + +void +MultiperspectivePerceptronTAGE::squash(ThreadID tid, void *bp_history) +{ + assert(bp_history); + MPPTAGEBranchInfo *bi = static_cast(bp_history); + delete bi; +} diff --git a/src/cpu/pred/multiperspective_perceptron_tage.hh b/src/cpu/pred/multiperspective_perceptron_tage.hh new file mode 100644 index 000000000..b18774e54 --- /dev/null +++ b/src/cpu/pred/multiperspective_perceptron_tage.hh @@ -0,0 +1,236 @@ +/* + * Copyright 2019 Texas A&M University + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Author: Daniel A. Jiménez + * Adapted to gem5 by: Javier Bueno Hedo + * + */ + +/* + * Multiperspective Perceptron Predictor with TAGE (by Daniel A. Jiménez) + */ + +#ifndef __CPU_PRED_MULTIPERSPECTIVE_PERCEPTRON_TAGE_HH__ +#define __CPU_PRED_MULTIPERSPECTIVE_PERCEPTRON_TAGE_HH__ + +#include "cpu/pred/loop_predictor.hh" +#include "cpu/pred/multiperspective_perceptron.hh" +#include "cpu/pred/statistical_corrector.hh" +#include "cpu/pred/tage_base.hh" +#include "params/MPP_LoopPredictor.hh" +#include "params/MPP_StatisticalCorrector.hh" +#include "params/MPP_TAGE.hh" +#include "params/MultiperspectivePerceptronTAGE.hh" + +class MPP_TAGE : public TAGEBase { + std::vector tunedHistoryLengths; + public: + struct BranchInfo : public TAGEBase::BranchInfo { + BranchInfo(TAGEBase &tage) : TAGEBase::BranchInfo(tage) + {} + virtual ~BranchInfo() + {} + }; + + MPP_TAGE(const MPP_TAGEParams *p) : TAGEBase(p), + tunedHistoryLengths(p->tunedHistoryLengths) + {} + + void calculateParameters() override; + void handleTAGEUpdate(Addr branch_pc, bool taken, TAGEBase::BranchInfo* bi) + override; + void handleAllocAndUReset(bool alloc, bool taken, TAGEBase::BranchInfo* bi, + int nrand) override; + void handleUReset() override; + void resetUctr(uint8_t &u) override; + int bindex(Addr pc_in) const override; + bool isHighConfidence(TAGEBase::BranchInfo *bi) const override; + + unsigned getUseAltIdx(TAGEBase::BranchInfo* bi, Addr branch_pc) override; + void adjustAlloc(bool & alloc, bool taken, bool pred_taken) override; + void updateHistories(ThreadID tid, Addr branch_pc, bool taken, + TAGEBase::BranchInfo* b, bool speculative, + const StaticInstPtr &inst, Addr target) override; + + void updatePathAndGlobalHistory(ThreadHistory& tHist, int brtype, + bool taken, Addr branch_pc, Addr target); +}; + +class MPP_LoopPredictor : public LoopPredictor { + public: + MPP_LoopPredictor(MPP_LoopPredictorParams *p) : LoopPredictor(p) + {} + + bool calcConf(int index) const override; + bool optionalAgeInc() const override; +}; + +class MPP_StatisticalCorrector : public StatisticalCorrector { + protected: + int8_t thirdH; + // global branch history variation GEHL + const unsigned pnb; + const unsigned logPnb; + std::vector pm; + std::vector * pgehl; + std::vector wp; + + // global branch history GEHL + const unsigned gnb; + const unsigned logGnb; + std::vector gm; + std::vector * ggehl; + std::vector wg; + + struct MPP_SCThreadHistory : public StatisticalCorrector::SCThreadHistory + { + MPP_SCThreadHistory() : globalHist(0), historyStack(16, 0), + historyStackPointer(0) {} + int64_t globalHist; // global history + std::vector historyStack; + unsigned int historyStackPointer; + + int64_t getHistoryStackEntry() const + { + return historyStack[historyStackPointer]; + } + + void updateHistoryStack(Addr target, bool taken, bool is_call, + bool is_return) + { + unsigned int truncated_target = target; + historyStack[historyStackPointer] = + (historyStack[historyStackPointer] << 1) ^ (truncated_target ^ + (truncated_target >> 5) ^ taken); + if (is_return) { + historyStackPointer = (historyStackPointer - 1) % + historyStack.size(); + } + if (is_call) { + int index = (historyStackPointer + 1) % historyStack.size(); + historyStack[index] = historyStack[historyStackPointer]; + historyStackPointer = index; + } + } + unsigned int getPointer() const { return historyStackPointer; } + }; + + public: + struct BranchInfo : public StatisticalCorrector::BranchInfo { + virtual ~BranchInfo() + {} + }; + MPP_StatisticalCorrector(const MPP_StatisticalCorrectorParams *p); + + void initBias() override; + unsigned getIndBias(Addr branch_pc, StatisticalCorrector::BranchInfo* bi, + bool bias) const override; + unsigned getIndBiasSK(Addr branch_pc, StatisticalCorrector::BranchInfo* bi) + const override; + unsigned getIndBiasBank(Addr branch_pc, + StatisticalCorrector::BranchInfo* bi, int hitBank, + int altBank) const override; + unsigned getIndUpd(Addr branch_pc) const override; + int gIndexLogsSubstr(int nbr, int i) override; + + bool scPredict(ThreadID tid, Addr branch_pc, bool cond_branch, + StatisticalCorrector::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) override; + + void condBranchUpdate(ThreadID tid, Addr branch_pc, bool taken, + StatisticalCorrector::BranchInfo *bi, + Addr corrTarget, bool b, int hitBank, int altBank, + int64_t phist) override; + + virtual void getBiasLSUM(Addr branch_pc, + StatisticalCorrector::BranchInfo *bi, int &lsum) const = 0; + + void gUpdate( + Addr branch_pc, bool taken, int64_t hist, std::vector & length, + std::vector * tab, int nbr, int logs, + std::vector &w, StatisticalCorrector::BranchInfo* bi) override; +}; + +class MultiperspectivePerceptronTAGE : public MultiperspectivePerceptron +{ + TAGEBase *tage; + LoopPredictor *loopPredictor; + StatisticalCorrector *statisticalCorrector; + + /** + * Branch information data type + */ + struct MPPTAGEBranchInfo : public MPPBranchInfo + { + TAGEBase::BranchInfo *tageBranchInfo; + LoopPredictor::BranchInfo *lpBranchInfo; + StatisticalCorrector::BranchInfo *scBranchInfo; + bool predictedTaken; + MPPTAGEBranchInfo(Addr pc, int pcshift, bool cond, TAGEBase &tage, + LoopPredictor &loopPredictor, + StatisticalCorrector &statisticalCorrector) + : MPPBranchInfo(pc, pcshift, cond), + tageBranchInfo(tage.makeBranchInfo()), + lpBranchInfo(loopPredictor.makeBranchInfo()), + scBranchInfo(statisticalCorrector.makeBranchInfo()), + predictedTaken(false) + {} + virtual ~MPPTAGEBranchInfo() + { + delete tageBranchInfo; + delete lpBranchInfo; + delete scBranchInfo; + } + }; + + unsigned int getIndex(ThreadID tid, MPPTAGEBranchInfo &bi, + const HistorySpec &spec, int index) const; + int computePartialSum(ThreadID tid, MPPTAGEBranchInfo &bi) const; + void updatePartial(ThreadID tid, MPPTAGEBranchInfo &bi, bool taken); + void updateHistories(ThreadID tid, MPPTAGEBranchInfo &bi, bool taken); + + public: + MultiperspectivePerceptronTAGE( + const MultiperspectivePerceptronTAGEParams *p); + + void init() override; + + bool lookup(ThreadID tid, Addr instPC, void * &bp_history) override; + + void update(ThreadID tid, Addr instPC, bool taken, + void *bp_history, bool squashed, + const StaticInstPtr & inst, + Addr corrTarget = MaxAddr) override; + void uncondBranch(ThreadID tid, Addr pc, void * &bp_history) override; + void squash(ThreadID tid, void *bp_history) override; + +}; +#endif//__CPU_PRED_MULTIPERSPECTIVE_PERCEPTRON_TAGE_HH__ diff --git a/src/cpu/pred/multiperspective_perceptron_tage_64KB.cc b/src/cpu/pred/multiperspective_perceptron_tage_64KB.cc new file mode 100644 index 000000000..9da21676b --- /dev/null +++ b/src/cpu/pred/multiperspective_perceptron_tage_64KB.cc @@ -0,0 +1,230 @@ +/* + * Copyright 2019 Texas A&M University + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Author: Daniel A. Jiménez + * Adapted to gem5 by: Javier Bueno Hedo + * + */ + +/* + * Multiperspective Perceptron Predictor with TAGE (by Daniel A. Jiménez) + * 64 KB version + */ + +#include "cpu/pred/multiperspective_perceptron_tage_64KB.hh" + +MPP_StatisticalCorrector_64KB::MPP_StatisticalCorrector_64KB( + const MPP_StatisticalCorrector_64KBParams *p) + : MPP_StatisticalCorrector(p), + numEntriesSecondLocalHistories(p->numEntriesSecondLocalHistories), + numEntriesThirdLocalHistories(p->numEntriesThirdLocalHistories), + snb(p->snb), + logSnb(p->logSnb), + sm(p->sm), + tnb(p->tnb), + logTnb(p->logTnb), + tm(p->tm) +{ + initGEHLTable(snb, sm, sgehl, logSnb, ws, -1); + initGEHLTable(tnb, tm, tgehl, logTnb, wt, -1); +} + +MPP_StatisticalCorrector_64KB::SCThreadHistory* +MPP_StatisticalCorrector_64KB::makeThreadHistory() +{ + MPP_SCThreadHistory *sh = new MPP_SCThreadHistory(); + + sh->setNumOrdinalHistories(3); + sh->initLocalHistory(1, numEntriesFirstLocalHistories, 4); + sh->initLocalHistory(2, numEntriesSecondLocalHistories, 5); + sh->initLocalHistory(3, numEntriesThirdLocalHistories, 3); + + return sh; +} + + +void +MPP_StatisticalCorrector_64KB::getBiasLSUM(Addr branch_pc, + StatisticalCorrector::BranchInfo* bi, int &lsum) const +{ + int8_t ctr = bias[getIndBias(branch_pc, bi, false /* unused */)]; + lsum += 2.09 * ctr; + ctr = biasSK[getIndBiasSK(branch_pc, bi)]; + lsum += 2.08 * ctr; +} + +int +MPP_StatisticalCorrector_64KB::gPredictions(ThreadID tid, Addr branch_pc, + StatisticalCorrector::BranchInfo* bi, int & lsum, int64_t phist) +{ + MPP_SCThreadHistory *sh = static_cast(scHistory); + unsigned int pc = branch_pc; + lsum += gPredict((pc << 1) + bi->predBeforeSC, sh->globalHist << 11, + gm, ggehl, gnb, logGnb, wg); + + // Local History #1 + lsum += 2.02 * gPredict(branch_pc, sh->getLocalHistory(1, branch_pc), + lm, lgehl, lnb, logLnb, wl); + if (sh->getLocalHistory(1, branch_pc) == 2047) lsum += 4; + if (sh->getLocalHistory(1, branch_pc) == 0) lsum -= 4; + + // Local History #3 + lsum += gPredict(branch_pc, sh->getLocalHistory(3, branch_pc) << 11, + tm, tgehl, tnb, logTnb, wt); + + // Local History #2 + lsum += gPredict(branch_pc, sh->getLocalHistory(2, branch_pc), + sm, sgehl, snb, logSnb, ws); + + lsum += gPredict(branch_pc, sh->getHistoryStackEntry(), + pm, pgehl, pnb, logPnb, wp); + + int thres = pUpdateThreshold[getIndUpd(branch_pc)]; + + return thres; +} + +void +MPP_StatisticalCorrector_64KB::gUpdates(ThreadID tid, Addr pc, bool taken, + StatisticalCorrector::BranchInfo* bi, int64_t phist) +{ + MPP_SCThreadHistory *sh = static_cast(scHistory); + + gUpdate((pc << 1) + bi->predBeforeSC, taken, sh->globalHist << 11, + gm, ggehl, gnb, logGnb, wg, bi); + + gUpdate(pc, taken, sh->getLocalHistory(1, pc), + lm, lgehl, lnb, logLnb, wl, bi); + + gUpdate(pc, taken, sh->getLocalHistory(2, pc), + sm, sgehl, snb, logSnb, ws, bi); + + gUpdate(pc, taken, sh->getLocalHistory(3, pc) << 11, + tm, tgehl, tnb, logTnb, wt, bi); + + gUpdate(pc, taken, sh->getHistoryStackEntry(), + pm, pgehl, pnb, logPnb, wp, bi); +} + +void +MPP_StatisticalCorrector_64KB::scHistoryUpdate(Addr branch_pc, + const StaticInstPtr &inst, bool taken, + StatisticalCorrector::BranchInfo *bi, Addr corrTarget) +{ + int brtype = inst->isDirectCtrl() ? 0 : 2; + if (! inst->isUncondCtrl()) { + ++brtype; + } + + MPP_SCThreadHistory *sh = static_cast(scHistory); + + if (brtype & 1) { + sh->globalHist = (sh->globalHist << 1) + taken; + sh->updateLocalHistory(2, branch_pc, taken, + (branch_pc ^ (branch_pc >> 4)) & 15); + sh->updateLocalHistory(3, branch_pc, taken); + } + sh->updateHistoryStack(corrTarget, taken, inst->isCall(), + inst->isReturn()); + + StatisticalCorrector::scHistoryUpdate(branch_pc, inst, taken, bi, + corrTarget); +} + +size_t +MPP_StatisticalCorrector_64KB::getSizeInBits() const +{ + size_t bits = 16; //global histories + + bits += (1 << logSizeUp) * pUpdateThresholdWidth; + + bits += scCountersWidth * 2 * (1 << logBias); //2 bias arrays + + bits += (gnb - 2) * (1 << logGnb) * (scCountersWidth - 1) + + (1 << (logGnb - 1)) * (2 * scCountersWidth - 1); + + bits += (pnb - 2) * (1 << logPnb) * (scCountersWidth - 1) + + (1 << (logPnb - 1)) * (2 * scCountersWidth - 1); + + bits += (lnb - 2) * (1 << logLnb) * (scCountersWidth - 1) + + (1 << (logLnb - 1)) * (2 * scCountersWidth - 1); + + bits += numEntriesFirstLocalHistories * lm[0]; + + bits += (snb - 2) * (1 << logSnb) * (scCountersWidth - 1) + + (1 << (logSnb - 1)) * (2 * scCountersWidth - 1); + + bits += numEntriesSecondLocalHistories * sm[0]; + + bits += (tnb - 2) * (1 << logTnb) * (scCountersWidth - 1) + + (1 << (logTnb - 1)) * (2 * scCountersWidth - 1); + + /* tm[0] is artificially increased by 11 to accomodate IMLI */ + bits += numEntriesThirdLocalHistories * (tm[0] - 11); + + bits += 16 * 16; // History stack + bits += 4; // History stack pointer + + bits += 3 * chooserConfWidth; // 3 chooser counters + + return bits; +} + +MPP_StatisticalCorrector_64KB* +MPP_StatisticalCorrector_64KBParams::create() +{ + return new MPP_StatisticalCorrector_64KB(this); +} + + +MultiperspectivePerceptronTAGE64KB::MultiperspectivePerceptronTAGE64KB( + const MultiperspectivePerceptronTAGE64KBParams *p) + : MultiperspectivePerceptronTAGE(p) +{ +} + +void +MultiperspectivePerceptronTAGE64KB::createSpecs() +{ + addSpec(new BLURRYPATH(5, 15, -1, 2.25, 0, 6, *this)); + addSpec(new BLURRYPATH(8, 10, -1, 2.25, 0, 6, *this)); + addSpec(new RECENCYPOS(31, 3.5, 0, 6, *this)); + addSpec(new GHISTMODPATH(3, 7, 1, 2.24, 0, 6, *this)); + addSpec(new MODPATH(3, 20, 3, 2.24, 0, 6, *this)); + addSpec(new IMLI(1, 2.23, 0, 6, *this)); + addSpec(new IMLI(4, 1.98, 0, 6, *this)); + addSpec(new RECENCY(9, 3, -1, 2.51, 0, 6, *this)); + addSpec(new ACYCLIC(12, -1, -1, 2.0, 0, 6, *this)); +} + +MultiperspectivePerceptronTAGE64KB* +MultiperspectivePerceptronTAGE64KBParams::create() +{ + return new MultiperspectivePerceptronTAGE64KB(this); +} diff --git a/src/cpu/pred/multiperspective_perceptron_tage_64KB.hh b/src/cpu/pred/multiperspective_perceptron_tage_64KB.hh new file mode 100644 index 000000000..aa5d37af3 --- /dev/null +++ b/src/cpu/pred/multiperspective_perceptron_tage_64KB.hh @@ -0,0 +1,88 @@ +/* + * Copyright 2019 Texas A&M University + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Author: Daniel A. Jiménez + * Adapted to gem5 by: Javier Bueno Hedo + * + */ + +/* + * Multiperspective Perceptron Predictor with TAGE (by Daniel A. Jiménez) + * 64 KB version + */ +#ifndef __CPU_PRED_MULTIPERSPECTIVE_PERCEPTRON_TAGE_64KB_HH__ +#define __CPU_PRED_MULTIPERSPECTIVE_PERCEPTRON_TAGE_64KB_HH__ + +#include "cpu/pred/multiperspective_perceptron_tage.hh" +#include "params/MPP_StatisticalCorrector_64KB.hh" +#include "params/MultiperspectivePerceptronTAGE64KB.hh" + +class MPP_StatisticalCorrector_64KB : public MPP_StatisticalCorrector { + const unsigned numEntriesSecondLocalHistories; + const unsigned numEntriesThirdLocalHistories; + + // Second local history GEHL + const unsigned snb; + const unsigned logSnb; + std::vector sm; + std::vector * sgehl; + std::vector ws; + + // Third local history GEHL + const unsigned tnb; + const unsigned logTnb; + std::vector tm; + std::vector * tgehl; + std::vector wt; + + StatisticalCorrector::SCThreadHistory *makeThreadHistory() override; + int gPredictions(ThreadID tid, Addr branch_pc, + StatisticalCorrector::BranchInfo* bi, int &lsum, int64_t phist) + override; + void getBiasLSUM(Addr branch_pc, + StatisticalCorrector::BranchInfo *bi, int &lsum) const override; + void gUpdates(ThreadID tid, Addr pc, bool taken, + StatisticalCorrector::BranchInfo* bi, int64_t phist) override; + void scHistoryUpdate(Addr branch_pc, const StaticInstPtr &inst, bool taken, + StatisticalCorrector::BranchInfo *bi, Addr corrTarget) override; + public: + MPP_StatisticalCorrector_64KB( + const MPP_StatisticalCorrector_64KBParams *p); + size_t getSizeInBits() const override; +}; + +class MultiperspectivePerceptronTAGE64KB : + public MultiperspectivePerceptronTAGE { + void createSpecs() override; + public: + MultiperspectivePerceptronTAGE64KB( + const MultiperspectivePerceptronTAGE64KBParams *p); +}; + +#endif // __CPU_PRED_MULTIPERSPECTIVE_PERCEPTRON_TAGE_64KB_HH__ diff --git a/src/cpu/pred/multiperspective_perceptron_tage_8KB.cc b/src/cpu/pred/multiperspective_perceptron_tage_8KB.cc new file mode 100644 index 000000000..872d817d5 --- /dev/null +++ b/src/cpu/pred/multiperspective_perceptron_tage_8KB.cc @@ -0,0 +1,196 @@ +/* + * Copyright 2019 Texas A&M University + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Author: Daniel A. Jiménez + * Adapted to gem5 by: Javier Bueno Hedo + * + */ + +/* + * Multiperspective Perceptron Predictor with TAGE (by Daniel A. Jiménez) + * 8 KB version + */ + +#include "cpu/pred/multiperspective_perceptron_tage_8KB.hh" + +MPP_TAGE_8KB* +MPP_TAGE_8KBParams::create() +{ + return new MPP_TAGE_8KB(this); +} + +MPP_LoopPredictor_8KB* +MPP_LoopPredictor_8KBParams::create() +{ + return new MPP_LoopPredictor_8KB(this); +} + +MPP_StatisticalCorrector_8KB::MPP_StatisticalCorrector_8KB( + const MPP_StatisticalCorrector_8KBParams *p) + : MPP_StatisticalCorrector(p) +{ +} + +MPP_StatisticalCorrector_8KB::SCThreadHistory* +MPP_StatisticalCorrector_8KB::makeThreadHistory() +{ + MPP_SCThreadHistory *sh = new MPP_SCThreadHistory(); + + sh->setNumOrdinalHistories(1); + sh->initLocalHistory(1, numEntriesFirstLocalHistories, 4); + + return sh; +} + +void +MPP_StatisticalCorrector_8KB::getBiasLSUM(Addr branch_pc, + StatisticalCorrector::BranchInfo* bi, int &lsum) const +{ + int8_t ctr = bias[getIndBias(branch_pc, bi, false /* unused */)]; + lsum += 2 * ctr + 1; + ctr = biasSK[getIndBiasSK(branch_pc, bi)]; + lsum += 2 * ctr + 1; +} + +int +MPP_StatisticalCorrector_8KB::gPredictions(ThreadID tid, Addr branch_pc, + StatisticalCorrector::BranchInfo* bi, int & lsum, int64_t phist) +{ + MPP_SCThreadHistory *sh = static_cast(scHistory); + unsigned int pc = branch_pc; + lsum += gPredict((pc << 1) + bi->predBeforeSC, sh->globalHist << 11, + gm, ggehl, gnb, logGnb, wg); + + // Local History #1 + lsum += 2 * gPredict(branch_pc, sh->getLocalHistory(1, branch_pc), + lm, lgehl, lnb, logLnb, wl); + if (sh->getLocalHistory(1, branch_pc) == 2047) lsum += 4; + if (sh->getLocalHistory(1, branch_pc) == 0) lsum -= 4; + + lsum += gPredict(branch_pc, sh->getHistoryStackEntry(), + pm, pgehl, pnb, logPnb, wp); + + int thres = pUpdateThreshold[getIndUpd(branch_pc)]; + + return thres; +} + +void +MPP_StatisticalCorrector_8KB::gUpdates(ThreadID tid, Addr pc, bool taken, + StatisticalCorrector::BranchInfo* bi, int64_t phist) +{ + MPP_SCThreadHistory *sh = static_cast(scHistory); + + gUpdate((pc << 1) + bi->predBeforeSC, taken, sh->globalHist << 11, + gm, ggehl, gnb, logGnb, wg, bi); + + gUpdate(pc, taken, sh->getLocalHistory(1, pc), + lm, lgehl, lnb, logLnb, wl, bi); + + gUpdate(pc, taken, sh->getHistoryStackEntry(), + pm, pgehl, pnb, logPnb, wp, bi); +} + +void +MPP_StatisticalCorrector_8KB::scHistoryUpdate(Addr branch_pc, + const StaticInstPtr &inst, bool taken, + StatisticalCorrector::BranchInfo *bi, Addr corrTarget) +{ + int brtype = inst->isDirectCtrl() ? 0 : 2; + if (! inst->isUncondCtrl()) { + ++brtype; + } + + MPP_SCThreadHistory *sh = static_cast(scHistory); + + if (brtype & 1) { + sh->globalHist = (sh->globalHist << 1) + taken; + } + sh->updateHistoryStack(corrTarget, taken, inst->isCall(), + inst->isReturn()); + + StatisticalCorrector::scHistoryUpdate(branch_pc, inst, taken, bi, + corrTarget); +} + +size_t +MPP_StatisticalCorrector_8KB::getSizeInBits() const +{ + size_t bits = 16; //global histories + + bits += (1 << logSizeUp) * pUpdateThresholdWidth; + + bits += scCountersWidth * 2 * (1 << logBias); //2 bias arrays + + bits += (gnb - 2) * (1 << logGnb) * (scCountersWidth - 1) + + (1 << (logGnb - 1)) * (2 * scCountersWidth - 1); + + bits += (pnb - 2) * (1 << logPnb) * (scCountersWidth - 1) + + (1 << (logPnb - 1)) * (2 * scCountersWidth - 1); + + bits += (lnb - 2) * (1 << logLnb) * (scCountersWidth - 1) + + (1 << (logLnb - 1)) * (2 * scCountersWidth - 1); + + bits += numEntriesFirstLocalHistories * lm[0]; + + bits += 16 * 16; // History stack + bits += 4; // History stack pointer + + bits += 3 * chooserConfWidth; // 3 chooser counters + + return bits; +} + +MPP_StatisticalCorrector_8KB* +MPP_StatisticalCorrector_8KBParams::create() +{ + return new MPP_StatisticalCorrector_8KB(this); +} + +MultiperspectivePerceptronTAGE8KB::MultiperspectivePerceptronTAGE8KB( + const MultiperspectivePerceptronTAGE8KBParams *p) + : MultiperspectivePerceptronTAGE(p) +{ +} + +void +MultiperspectivePerceptronTAGE8KB::createSpecs() +{ + addSpec(new BLURRYPATH(5, 15, -1, 2.25, 0, 6, *this)); + addSpec(new RECENCYPOS(31, 3.5, 0, 6, *this)); + addSpec(new GHISTMODPATH(3, 7, 1, 2.24, 0, 6, *this)); + addSpec(new IMLI(1, 2.23, 0, 6, *this)); + addSpec(new IMLI(4, 1.98, 0, 6, *this)); +} + +MultiperspectivePerceptronTAGE8KB* +MultiperspectivePerceptronTAGE8KBParams::create() +{ + return new MultiperspectivePerceptronTAGE8KB(this); +} diff --git a/src/cpu/pred/multiperspective_perceptron_tage_8KB.hh b/src/cpu/pred/multiperspective_perceptron_tage_8KB.hh new file mode 100644 index 000000000..1bfec931b --- /dev/null +++ b/src/cpu/pred/multiperspective_perceptron_tage_8KB.hh @@ -0,0 +1,84 @@ +/* + * Copyright 2019 Texas A&M University + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Author: Daniel A. Jiménez + * Adapted to gem5 by: Javier Bueno Hedo + * + */ + +/* + * Multiperspective Perceptron Predictor with TAGE (by Daniel A. Jiménez) + * 8 KB version + */ + +#ifndef __CPU_PRED_MULTIPERSPECTIVE_PERCEPTRON_TAGE_8KB_HH__ +#define __CPU_PRED_MULTIPERSPECTIVE_PERCEPTRON_TAGE_8KB_HH__ + +#include "cpu/pred/multiperspective_perceptron_tage.hh" +#include "params/MPP_LoopPredictor_8KB.hh" +#include "params/MPP_StatisticalCorrector_8KB.hh" +#include "params/MPP_TAGE_8KB.hh" +#include "params/MultiperspectivePerceptronTAGE8KB.hh" + +class MPP_TAGE_8KB : public MPP_TAGE { + public: + MPP_TAGE_8KB(const MPP_TAGE_8KBParams *p) : MPP_TAGE(p) {} +}; + +class MPP_LoopPredictor_8KB : public MPP_LoopPredictor { + public: + MPP_LoopPredictor_8KB(MPP_LoopPredictor_8KBParams *p) : + MPP_LoopPredictor(p) {} +}; + +class MPP_StatisticalCorrector_8KB : public MPP_StatisticalCorrector { + StatisticalCorrector::SCThreadHistory *makeThreadHistory() override; + int gPredictions(ThreadID tid, Addr branch_pc, + StatisticalCorrector::BranchInfo* bi, int &lsum, int64_t phist) + override; + void getBiasLSUM(Addr branch_pc, + StatisticalCorrector::BranchInfo *bi, int &lsum) const override; + void gUpdates(ThreadID tid, Addr pc, bool taken, + StatisticalCorrector::BranchInfo* bi, int64_t phist) override; + void scHistoryUpdate(Addr branch_pc, const StaticInstPtr &inst, bool taken, + StatisticalCorrector::BranchInfo *bi, Addr corrTarget) override; + public: + MPP_StatisticalCorrector_8KB(const MPP_StatisticalCorrector_8KBParams *p); + size_t getSizeInBits() const override; +}; + +class MultiperspectivePerceptronTAGE8KB : + public MultiperspectivePerceptronTAGE { + void createSpecs() override; + public: + MultiperspectivePerceptronTAGE8KB( + const MultiperspectivePerceptronTAGE8KBParams *p); +}; + +#endif // __CPU_PRED_MULTIPERSPECTIVE_PERCEPTRON_TAGE_8KB_HH__ diff --git a/src/cpu/pred/statistical_corrector.cc b/src/cpu/pred/statistical_corrector.cc index ebacd4dad..8ddae9be2 100644 --- a/src/cpu/pred/statistical_corrector.cc +++ b/src/cpu/pred/statistical_corrector.cc @@ -69,17 +69,34 @@ { wb.resize(1 << logSizeUps, 4); - initGEHLTable(lnb, lm, lgehl, logLnb, wl, 7); - initGEHLTable(bwnb, bwm, bwgehl, logBwnb, wbw, 7); - initGEHLTable(inb, im, igehl, logInb, wi, 7); + initGEHLTable(lnb, lm, lgehl, logLnb, wl, p->lWeightInitValue); + initGEHLTable(bwnb, bwm, bwgehl, logBwnb, wbw, p->bwWeightInitValue); + initGEHLTable(inb, im, igehl, logInb, wi, p->iWeightInitValue); updateThreshold = 35 << 3; - pUpdateThreshold.resize(1 << logSizeUp, 0); + pUpdateThreshold.resize(1 << logSizeUp, p->initialUpdateThresholdValue); bias.resize(1 << logBias); biasSK.resize(1 << logBias); biasBank.resize(1 << logBias); +} + +StatisticalCorrector::BranchInfo* +StatisticalCorrector::makeBranchInfo() +{ + return new BranchInfo(); +} + +StatisticalCorrector::SCThreadHistory* +StatisticalCorrector::makeThreadHistory() +{ + return new SCThreadHistory(); +} + +void +StatisticalCorrector::initBias() +{ for (int j = 0; j < (1 << logBias); j++) { switch (j & 3) { case 0: @@ -106,18 +123,6 @@ } } -StatisticalCorrector::BranchInfo* -StatisticalCorrector::makeBranchInfo() -{ - return new BranchInfo(); -} - -StatisticalCorrector::SCThreadHistory* -StatisticalCorrector::makeThreadHistory() -{ - return new SCThreadHistory(); -} - void StatisticalCorrector::initGEHLTable(unsigned numLenghts, std::vector lengths, std::vector * & table, @@ -218,7 +223,7 @@ bool StatisticalCorrector::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 hitBank, int altBank, int64_t phist, int init_lsum) { bool pred_taken = prev_pred_taken; if (cond_branch) { @@ -232,7 +237,7 @@ StatisticalCorrector::scPredict(ThreadID tid, Addr branch_pc, bool cond_branch, bi->highConf = (abs(2 * conf_ctr + 1) >= (1<isDirectCtrl() ? 0 : 2; + if (! inst->isUncondCtrl()) { + ++brtype; + } // Non speculative SC histories update if (brtype & 1) { if (corrTarget < branch_pc) { @@ -376,6 +386,14 @@ void StatisticalCorrector::init() { scHistory = makeThreadHistory(); + initBias(); +} + +size_t +StatisticalCorrector::getSizeInBits() const +{ + // Not implemented + return 0; } void diff --git a/src/cpu/pred/statistical_corrector.hh b/src/cpu/pred/statistical_corrector.hh index f96684346..2e8e50240 100644 --- a/src/cpu/pred/statistical_corrector.hh +++ b/src/cpu/pred/statistical_corrector.hh @@ -44,24 +44,27 @@ #include "base/statistics.hh" #include "base/types.hh" +#include "cpu/static_inst.hh" #include "sim/sim_object.hh" struct StatisticalCorrectorParams; class StatisticalCorrector : public SimObject { + protected: template inline void ctrUpdate(T & ctr, bool taken, int nbits) { assert(nbits <= sizeof(T) << 3); - if (taken) { - if (ctr < ((1 << (nbits - 1)) - 1)) - ctr++; - } else { - if (ctr > -(1 << (nbits - 1))) - ctr--; + if (nbits > 0) { + if (taken) { + if (ctr < ((1 << (nbits - 1)) - 1)) + ctr++; + } else { + if (ctr > -(1 << (nbits - 1))) + ctr--; + } } } - protected: // histories used for the statistical corrector struct SCThreadHistory { SCThreadHistory() { @@ -209,20 +212,22 @@ class StatisticalCorrector : public SimObject virtual BranchInfo *makeBranchInfo(); virtual SCThreadHistory *makeThreadHistory(); - bool scPredict( + virtual void initBias(); + + 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); + int64_t phist, int init_lsum = 0); - unsigned getIndBias(Addr branch_pc, BranchInfo* bi, bool b) const; + virtual unsigned getIndBias(Addr branch_pc, BranchInfo* bi, bool b) const; - unsigned getIndBiasSK(Addr branch_pc, BranchInfo* bi) const; + virtual unsigned getIndBiasSK(Addr branch_pc, BranchInfo* bi) const; virtual unsigned getIndBiasBank( Addr branch_pc, BranchInfo* bi, int hitBank, int altBank) const = 0; - unsigned getIndUpd(Addr branch_pc) const; + virtual unsigned getIndUpd(Addr branch_pc) const; unsigned getIndUpds(Addr branch_pc) const; virtual int gPredictions(ThreadID tid, Addr branch_pc, BranchInfo* bi, @@ -237,7 +242,7 @@ class StatisticalCorrector : public SimObject std::vector * tab, int nbr, int logs, std::vector & w); - void gUpdate( + virtual void gUpdate( Addr branch_pc, bool taken, int64_t hist, std::vector & length, std::vector * tab, int nbr, int logs, std::vector & w, BranchInfo* bi); @@ -248,8 +253,8 @@ class StatisticalCorrector : public SimObject std::vector & w, int8_t wInitValue); virtual void scHistoryUpdate( - Addr branch_pc, int brtype, bool taken, BranchInfo * tage_bi, - Addr corrTarget); + 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; @@ -258,8 +263,10 @@ class StatisticalCorrector : public SimObject void regStats() override; void updateStats(bool taken, BranchInfo *bi); - void condBranchUpdate(ThreadID tid, Addr branch_pc, bool taken, + 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 size_t getSizeInBits() const; }; #endif//__CPU_PRED_STATISTICAL_CORRECTOR_HH diff --git a/src/cpu/pred/tage_base.cc b/src/cpu/pred/tage_base.cc index 2d149ea76..4f6091bb8 100644 --- a/src/cpu/pred/tage_base.cc +++ b/src/cpu/pred/tage_base.cc @@ -59,12 +59,14 @@ TAGEBase::TAGEBase(const TAGEBaseParams *p) logTagTableSizes(p->logTagTableSizes), threadHistory(p->numThreads), logUResetPeriod(p->logUResetPeriod), + initialTCounterValue(p->initialTCounterValue), numUseAltOnNa(p->numUseAltOnNa), useAltOnNaBits(p->useAltOnNaBits), maxNumAlloc(p->maxNumAlloc), noSkip(p->noSkip), speculativeHistUpdate(p->speculativeHistUpdate), - instShiftAmt(p->instShiftAmt) + instShiftAmt(p->instShiftAmt), + initialized(false) { if (noSkip.empty()) { // Set all the table to enabled by default @@ -80,6 +82,9 @@ TAGEBase::makeBranchInfo() { void TAGEBase::init() { + if (initialized) { + return; + } // Current method for periodically resetting the u counter bits only // works for 1 or 2 bits // Also make sure that it is not 0 @@ -91,7 +96,7 @@ TAGEBase::init() // initialize the counter to half of the period assert(logUResetPeriod != 0); - tCounter = ULL(1) << (logUResetPeriod - 1); + tCounter = initialTCounterValue; assert(histBufferSize > maxHist * 2); @@ -134,6 +139,7 @@ TAGEBase::init() tableIndices = new int [nHistoryTables+1]; tableTags = new int [nHistoryTables+1]; + initialized = true; } void @@ -339,7 +345,7 @@ TAGEBase::calculateIndicesAndTags(ThreadID tid, Addr branch_pc, } unsigned -TAGEBase::getUseAltIdx(BranchInfo* bi) +TAGEBase::getUseAltIdx(BranchInfo* bi, Addr branch_pc) { // There is only 1 counter on the base TAGE implementation return 0; @@ -397,8 +403,8 @@ TAGEBase::tagePredict(ThreadID tid, Addr branch_pc, //if the entry is recognized as a newly allocated entry and //useAltPredForNewlyAllocated is positive use the alternate //prediction - if ((useAltPredForNewlyAllocated[getUseAltIdx(bi)] < 0) || - ! bi->pseudoNewAlloc) { + if ((useAltPredForNewlyAllocated[getUseAltIdx(bi, branch_pc)] < 0) + || ! bi->pseudoNewAlloc) { bi->tagePred = bi->longestMatchPred; bi->provider = TAGE_LONGEST_MATCH; } else { @@ -501,11 +507,16 @@ TAGEBase::resetUctr(uint8_t & u) void TAGEBase::condBranchUpdate(ThreadID tid, Addr branch_pc, bool taken, - BranchInfo* bi, int nrand, Addr corrTarget, bool pred) + BranchInfo* bi, int nrand, Addr corrTarget, bool pred, bool preAdjustAlloc) { // TAGE UPDATE // try to allocate a new entries only if prediction was wrong bool alloc = (bi->tagePred != taken) && (bi->hitBank < nHistoryTables); + + if (preAdjustAlloc) { + adjustAlloc(alloc, taken, pred); + } + if (bi->hitBank > 0) { // Manage the selection between longest matching and alternate // matching for "pseudo"-newly allocated longest matching entry @@ -519,13 +530,16 @@ TAGEBase::condBranchUpdate(ThreadID tid, Addr branch_pc, bool taken, // if it was delivering the correct prediction, no need to // allocate new entry even if the overall prediction was false if (bi->longestMatchPred != bi->altTaken) { - ctrUpdate(useAltPredForNewlyAllocated[getUseAltIdx(bi)], - bi->altTaken == taken, useAltOnNaBits); + ctrUpdate( + useAltPredForNewlyAllocated[getUseAltIdx(bi, branch_pc)], + bi->altTaken == taken, useAltOnNaBits); } } } - adjustAlloc(alloc, taken, pred); + if (!preAdjustAlloc) { + adjustAlloc(alloc, taken, pred); + } handleAllocAndUReset(alloc, taken, bi, nrand); @@ -789,6 +803,23 @@ TAGEBase::isSpeculativeUpdateEnabled() const return speculativeHistUpdate; } +size_t +TAGEBase::getSizeInBits() const { + size_t bits = 0; + for (int i = 1; i <= nHistoryTables; i++) { + bits += (1 << logTagTableSizes[i]) * + (tagTableCounterBits + tagTableUBits + tagTableTagWidths[i]); + } + uint64_t bimodalTableSize = ULL(1) << logTagTableSizes[0]; + bits += numUseAltOnNa * useAltOnNaBits; + bits += bimodalTableSize; + bits += (bimodalTableSize >> logRatioBiModalHystEntries); + bits += histLengths[nHistoryTables]; + bits += pathHistBits; + bits += logUResetPeriod; + return bits; +} + TAGEBase* TAGEBaseParams::create() { diff --git a/src/cpu/pred/tage_base.hh b/src/cpu/pred/tage_base.hh index 48daaf9af..9d5451e56 100644 --- a/src/cpu/pred/tage_base.hh +++ b/src/cpu/pred/tage_base.hh @@ -318,10 +318,12 @@ class TAGEBase : public SimObject * @nrand Random int number from 0 to 3 * @param corrTarget The correct branch target * @param pred Final prediction for this branch + * @param preAdjustAlloc call adjustAlloc before checking + * pseudo newly allocated entries */ virtual void condBranchUpdate( ThreadID tid, Addr branch_pc, bool taken, BranchInfo* bi, - int nrand, Addr corrTarget, bool pred); + int nrand, Addr corrTarget, bool pred, bool preAdjustAlloc = false); /** * TAGE prediction called from TAGE::predict @@ -364,7 +366,7 @@ class TAGEBase : public SimObject * Calculation of the index for useAltPredForNewlyAllocated * On this base TAGE implementation it is always 0 */ - virtual unsigned getUseAltIdx(BranchInfo* bi); + virtual unsigned getUseAltIdx(BranchInfo* bi, Addr branch_pc); /** * Extra calculation to tell whether TAGE allocaitons may happen or not @@ -401,12 +403,18 @@ class TAGEBase : public SimObject */ virtual void extraAltCalc(BranchInfo* bi); + virtual bool isHighConfidence(BranchInfo* bi) const + { + return false; + } + void btbUpdate(ThreadID tid, Addr branch_addr, BranchInfo* &bi); unsigned getGHR(ThreadID tid, BranchInfo *bi) const; int8_t getCtr(int hitBank, int hitBankIndex) const; unsigned getTageCtrBits() const; int getPathHist(ThreadID tid) const; bool isSpeculativeUpdateEnabled() const; + size_t getSizeInBits() const; protected: const unsigned logRatioBiModalHystEntries; @@ -462,6 +470,7 @@ class TAGEBase : public SimObject std::vector useAltPredForNewlyAllocated; int64_t tCounter; uint64_t logUResetPeriod; + const int64_t initialTCounterValue; unsigned numUseAltOnNa; unsigned useAltOnNaBits; unsigned maxNumAlloc; @@ -475,6 +484,8 @@ class TAGEBase : public SimObject const unsigned instShiftAmt; + bool initialized; + // stats Stats::Scalar tageLongestMatchProviderCorrect; Stats::Scalar tageAltMatchProviderCorrect; diff --git a/src/cpu/pred/tage_sc_l.cc b/src/cpu/pred/tage_sc_l.cc index 5f17b8187..de7c2f22c 100644 --- a/src/cpu/pred/tage_sc_l.cc +++ b/src/cpu/pred/tage_sc_l.cc @@ -168,7 +168,7 @@ TAGE_SC_L_TAGE::calculateIndicesAndTags( } unsigned -TAGE_SC_L_TAGE::getUseAltIdx(TAGEBase::BranchInfo* bi) +TAGE_SC_L_TAGE::getUseAltIdx(TAGEBase::BranchInfo* bi, Addr branch_pc) { BranchInfo *tbi = static_cast(bi); unsigned idx; @@ -457,12 +457,7 @@ TAGE_SC_L::update(ThreadID tid, Addr branch_pc, bool taken, void *bp_history, } if (!tage->isSpeculativeUpdateEnabled()) { - int brtype = inst->isDirectCtrl() ? 0 : 2; - if (! inst->isUncondCtrl()) { - ++brtype; - } - - statisticalCorrector->scHistoryUpdate(branch_pc, brtype, taken, + statisticalCorrector->scHistoryUpdate(branch_pc, inst, taken, bi->scBranchInfo, corrTarget); tage->updateHistories(tid, branch_pc, taken, bi->tageBranchInfo, false, diff --git a/src/cpu/pred/tage_sc_l.hh b/src/cpu/pred/tage_sc_l.hh index c96cc8960..b3629ab7e 100644 --- a/src/cpu/pred/tage_sc_l.hh +++ b/src/cpu/pred/tage_sc_l.hh @@ -94,7 +94,7 @@ class TAGE_SC_L_TAGE : public TAGEBase { void calculateIndicesAndTags( ThreadID tid, Addr branch_pc, TAGEBase::BranchInfo* bi) override; - unsigned getUseAltIdx(TAGEBase::BranchInfo* bi) override; + unsigned getUseAltIdx(TAGEBase::BranchInfo* bi, Addr branch_pc) override; void updateHistories( ThreadID tid, Addr branch_pc, bool taken, TAGEBase::BranchInfo* b, diff --git a/src/cpu/pred/tage_sc_l_64KB.cc b/src/cpu/pred/tage_sc_l_64KB.cc index 164d58768..72676e709 100644 --- a/src/cpu/pred/tage_sc_l_64KB.cc +++ b/src/cpu/pred/tage_sc_l_64KB.cc @@ -139,8 +139,13 @@ TAGE_SC_L_64KB_StatisticalCorrector::gIndexLogsSubstr(int nbr, int i) void TAGE_SC_L_64KB_StatisticalCorrector::scHistoryUpdate(Addr branch_pc, - int brtype, bool taken, BranchInfo* tage_bi, Addr corrTarget) + const StaticInstPtr &inst, bool taken, BranchInfo* tage_bi, + Addr corrTarget) { + int brtype = inst->isDirectCtrl() ? 0 : 2; + if (! inst->isUncondCtrl()) { + ++brtype; + } // Non speculative SC histories update if (brtype & 1) { SC_64KB_ThreadHistory *sh = @@ -152,7 +157,7 @@ TAGE_SC_L_64KB_StatisticalCorrector::scHistoryUpdate(Addr branch_pc, sh->updateLocalHistory(3, branch_pc, taken); } - StatisticalCorrector::scHistoryUpdate(branch_pc, brtype, taken, tage_bi, + StatisticalCorrector::scHistoryUpdate(branch_pc, inst, taken, tage_bi, corrTarget); } diff --git a/src/cpu/pred/tage_sc_l_64KB.hh b/src/cpu/pred/tage_sc_l_64KB.hh index 21dd1703c..4928ba5be 100644 --- a/src/cpu/pred/tage_sc_l_64KB.hh +++ b/src/cpu/pred/tage_sc_l_64KB.hh @@ -118,7 +118,7 @@ class TAGE_SC_L_64KB_StatisticalCorrector : public StatisticalCorrector int gIndexLogsSubstr(int nbr, int i) override; - void scHistoryUpdate(Addr branch_pc, int brtype, bool taken, + void scHistoryUpdate(Addr branch_pc, const StaticInstPtr &inst, bool taken, BranchInfo * tage_bi, Addr corrTarget) override; void gUpdates(ThreadID tid, Addr pc, bool taken, BranchInfo* bi, diff --git a/src/cpu/pred/tage_sc_l_8KB.cc b/src/cpu/pred/tage_sc_l_8KB.cc index 9af21e1a5..2455990d4 100644 --- a/src/cpu/pred/tage_sc_l_8KB.cc +++ b/src/cpu/pred/tage_sc_l_8KB.cc @@ -101,9 +101,14 @@ int TAGE_SC_L_8KB_StatisticalCorrector::gIndexLogsSubstr(int nbr, int i) } void -TAGE_SC_L_8KB_StatisticalCorrector::scHistoryUpdate(Addr branch_pc, int brtype, - bool taken, BranchInfo * tage_bi, Addr corrTarget) +TAGE_SC_L_8KB_StatisticalCorrector::scHistoryUpdate(Addr branch_pc, + const StaticInstPtr &inst, bool taken, BranchInfo *tage_bi, + Addr corrTarget) { + int brtype = inst->isDirectCtrl() ? 0 : 2; + if (! inst->isUncondCtrl()) { + ++brtype; + } // Non speculative SC histories update if (brtype & 1) { SC_8KB_ThreadHistory *sh = @@ -111,7 +116,7 @@ TAGE_SC_L_8KB_StatisticalCorrector::scHistoryUpdate(Addr branch_pc, int brtype, sh->globalHist = (sh->globalHist << 1) + taken; } - StatisticalCorrector::scHistoryUpdate(branch_pc, brtype, taken, tage_bi, + StatisticalCorrector::scHistoryUpdate(branch_pc, inst, taken, tage_bi, corrTarget); } diff --git a/src/cpu/pred/tage_sc_l_8KB.hh b/src/cpu/pred/tage_sc_l_8KB.hh index 74193b020..7730463b1 100644 --- a/src/cpu/pred/tage_sc_l_8KB.hh +++ b/src/cpu/pred/tage_sc_l_8KB.hh @@ -99,8 +99,8 @@ class TAGE_SC_L_8KB_StatisticalCorrector : public StatisticalCorrector int gIndexLogsSubstr(int nbr, int i) override; void scHistoryUpdate( - Addr branch_pc, int brtype, bool taken, BranchInfo * tage_bi, - Addr corrTarget) override; + Addr branch_pc, const StaticInstPtr &inst, bool taken, + BranchInfo * tage_bi, Addr corrTarget) override; void gUpdates(ThreadID tid, Addr pc, bool taken, BranchInfo* bi, int64_t phist) override; -- 2.30.2