cpu: Added the Multiperspective Perceptron Predictor with TAGE (8KB and 64KB)

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 <noreply+kokoro@google.com>
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-by: Ilias Vougioukas <ilias.vougioukas@arm.com>
This commit is contained in:
Javier Bueno Hedo
2019-06-12 15:42:19 +02:00
parent b81a66d775
commit 61a9980933
22 changed files with 1909 additions and 77 deletions

View File

@@ -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()

View File

@@ -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')

View File

@@ -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()
{

View File

@@ -259,5 +259,7 @@ class LoopPredictor : public SimObject
void regStats() override;
LoopPredictor(LoopPredictorParams *p);
size_t getSizeInBits() const;
};
#endif//__CPU_PRED_LOOP_PREDICTOR_HH__

View File

@@ -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<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,
@@ -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<int>() % 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<int>() %
threadData[tid]->filterTable.size();
FilterEntry &frand = threadData[tid]->filterTable[rnd];
if (frand.seenTaken && frand.seenUntaken) {
threadData[tid]->occupancy -= 1;

View File

@@ -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<int> imli_counter_bits;
std::vector<int> modhist_indices;
std::vector<int> 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;

View File

@@ -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<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;
}

View File

@@ -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<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__

View File

@@ -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<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);
}

View File

@@ -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<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__

View File

@@ -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<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);
}

View File

@@ -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__

View File

@@ -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<int> lengths, std::vector<int8_t> * & 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<<conf_bits) - 1);
}
int lsum = 0;
int lsum = init_lsum;
int8_t ctr = bias[getIndBias(branch_pc, bi, bias_bit)];
lsum += (2 * ctr + 1);
@@ -280,9 +285,14 @@ StatisticalCorrector::scPredict(ThreadID tid, Addr branch_pc, bool cond_branch,
}
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) {
@@ -376,6 +386,14 @@ void
StatisticalCorrector::init()
{
scHistory = makeThreadHistory();
initBias();
}
size_t
StatisticalCorrector::getSizeInBits() const
{
// Not implemented
return 0;
}
void

View File

@@ -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<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() {
@@ -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<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);
@@ -248,8 +253,8 @@ class StatisticalCorrector : public SimObject
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;
@@ -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

View File

@@ -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()
{

View File

@@ -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<int8_t> 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;

View File

@@ -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<BranchInfo *>(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,

View File

@@ -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,

View File

@@ -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);
}

View File

@@ -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,

View File

@@ -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);
}

View File

@@ -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;