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,
pathHistBits = 27
maxNumAlloc = 2
logUResetPeriod = 10
+ initialTCounterValue = 1 << 9
useAltOnNaBits = 5
# TODO No speculation implemented as of now
speculativeHistUpdate = False
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")
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
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'
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
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'
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()
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')
"the prediction is wrong");
}
+size_t
+LoopPredictor::getSizeInBits() const
+{
+ return (1ULL << logSizeLoopPred) *
+ ((useSpeculation ? 3 : 2) * loopTableIterBits +
+ loopTableConfidenceBits + loopTableTagBits +
+ loopTableAgeBits + useDirectionBit);
+}
+
LoopPredictor *
LoopPredictorParams::create()
{
void regStats() override;
LoopPredictor(LoopPredictorParams *p);
+
+ size_t getSizeInBits() const;
};
#endif//__CPU_PRED_LOOP_PREDICTOR_HH__
#include "cpu/pred/multiperspective_perceptron.hh"
+#include "base/random.hh"
#include "debug/Branch.hh"
int
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()
{
static_cast<const MultiperspectivePerceptronParams *>(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,
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;
do {
// udpate a random weight
int besti = -1;
- int nrand = rand_r(&randSeed) % specs.size();
+ int nrand = random_mt.random<int>() % specs.size();
int pout;
found = false;
for (int j = 0; j < specs.size(); j += 1) {
// 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<int>() %
+ threadData[tid]->filterTable.size();
FilterEntry &frand = threadData[tid]->filterTable[rnd];
if (frand.seenTaken && frand.seenUntaken) {
threadData[tid]->occupancy -= 1;
int ghist_length;
int modghist_length;
int path_length;
- unsigned int randSeed;
int thresholdCounter;
int theta;
+ int extrabits;
std::vector<int> imli_counter_bits;
std::vector<int> modhist_indices;
std::vector<int> modhist_lengths;
* @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
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;
--- /dev/null
+/*
+ * 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<int>() & 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<int>() & 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<int>() & 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<int> & length, std::vector<int8_t> * tab,
+ int nbr, int logs, std::vector<int8_t> & 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<std::vector<unsigned int>> &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<MPPTAGEBranchInfo*>(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<int>(), 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<MPPTAGEBranchInfo*>(bp_history);
+ delete bi;
+}
--- /dev/null
+/*
+ * 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<unsigned int> 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<int> pm;
+ std::vector<int8_t> * pgehl;
+ std::vector<int8_t> wp;
+
+ // global branch history GEHL
+ const unsigned gnb;
+ const unsigned logGnb;
+ std::vector<int> gm;
+ std::vector<int8_t> * ggehl;
+ std::vector<int8_t> wg;
+
+ struct MPP_SCThreadHistory : public StatisticalCorrector::SCThreadHistory
+ {
+ MPP_SCThreadHistory() : globalHist(0), historyStack(16, 0),
+ historyStackPointer(0) {}
+ int64_t globalHist; // global history
+ std::vector<int64_t> 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<int> & length,
+ std::vector<int8_t> * tab, int nbr, int logs,
+ std::vector<int8_t> &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__
--- /dev/null
+/*
+ * 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<MPP_SCThreadHistory *>(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<MPP_SCThreadHistory *>(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<MPP_SCThreadHistory *>(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);
+}
--- /dev/null
+/*
+ * 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<int> sm;
+ std::vector<int8_t> * sgehl;
+ std::vector<int8_t> ws;
+
+ // Third local history GEHL
+ const unsigned tnb;
+ const unsigned logTnb;
+ std::vector<int> tm;
+ std::vector<int8_t> * tgehl;
+ std::vector<int8_t> 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__
--- /dev/null
+/*
+ * 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<MPP_SCThreadHistory *>(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<MPP_SCThreadHistory *>(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<MPP_SCThreadHistory *>(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);
+}
--- /dev/null
+/*
+ * 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__
{
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:
}
}
-StatisticalCorrector::BranchInfo*
-StatisticalCorrector::makeBranchInfo()
-{
- return new BranchInfo();
-}
-
-StatisticalCorrector::SCThreadHistory*
-StatisticalCorrector::makeThreadHistory()
-{
- return new SCThreadHistory();
-}
-
void
StatisticalCorrector::initGEHLTable(unsigned numLenghts,
std::vector<int> lengths, std::vector<int8_t> * & table,
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) {
bi->highConf = (abs(2 * conf_ctr + 1) >= (1<<conf_bits) - 1);
}
- int lsum = 0;
+ int lsum = init_lsum;
int8_t ctr = bias[getIndBias(branch_pc, bi, bias_bit)];
lsum += (2 * ctr + 1);
}
void
-StatisticalCorrector::scHistoryUpdate(Addr branch_pc, int brtype, bool taken,
- BranchInfo * tage_bi, Addr corrTarget)
+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) {
if (corrTarget < branch_pc) {
StatisticalCorrector::init()
{
scHistory = makeThreadHistory();
+ initBias();
+}
+
+size_t
+StatisticalCorrector::getSizeInBits() const
+{
+ // Not implemented
+ return 0;
}
void
#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<typename T>
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() {
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,
std::vector<int8_t> * tab, int nbr, int logs,
std::vector<int8_t> & w);
- void gUpdate(
+ 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);
std::vector<int8_t> & 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;
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
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
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
// initialize the counter to half of the period
assert(logUResetPeriod != 0);
- tCounter = ULL(1) << (logUResetPeriod - 1);
+ tCounter = initialTCounterValue;
assert(histBufferSize > maxHist * 2);
tableIndices = new int [nHistoryTables+1];
tableTags = new int [nHistoryTables+1];
+ initialized = true;
}
void
}
unsigned
-TAGEBase::getUseAltIdx(BranchInfo* bi)
+TAGEBase::getUseAltIdx(BranchInfo* bi, Addr branch_pc)
{
// There is only 1 counter on the base TAGE implementation
return 0;
//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 {
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
// 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);
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()
{
* @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
* 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
*/
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;
std::vector<int8_t> useAltPredForNewlyAllocated;
int64_t tCounter;
uint64_t logUResetPeriod;
+ const int64_t initialTCounterValue;
unsigned numUseAltOnNa;
unsigned useAltOnNaBits;
unsigned maxNumAlloc;
const unsigned instShiftAmt;
+ bool initialized;
+
// stats
Stats::Scalar tageLongestMatchProviderCorrect;
Stats::Scalar tageAltMatchProviderCorrect;
}
unsigned
-TAGE_SC_L_TAGE::getUseAltIdx(TAGEBase::BranchInfo* bi)
+TAGE_SC_L_TAGE::getUseAltIdx(TAGEBase::BranchInfo* bi, Addr branch_pc)
{
BranchInfo *tbi = static_cast<BranchInfo *>(bi);
unsigned idx;
}
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,
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,
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 =
sh->updateLocalHistory(3, branch_pc, taken);
}
- StatisticalCorrector::scHistoryUpdate(branch_pc, brtype, taken, tage_bi,
+ StatisticalCorrector::scHistoryUpdate(branch_pc, inst, taken, tage_bi,
corrTarget);
}
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,
}
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 =
sh->globalHist = (sh->globalHist << 1) + taken;
}
- StatisticalCorrector::scHistoryUpdate(branch_pc, brtype, taken, tage_bi,
+ StatisticalCorrector::scHistoryUpdate(branch_pc, inst, taken, tage_bi,
corrTarget);
}
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;