summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configs/common/O3_ARM_v7a.py1
-rw-r--r--src/cpu/inorder/resources/bpred_unit.cc3
-rw-r--r--src/cpu/o3/bpred_unit_impl.hh3
-rw-r--r--src/cpu/pred/tournament.cc92
-rw-r--r--src/cpu/pred/tournament.hh46
5 files changed, 85 insertions, 60 deletions
diff --git a/configs/common/O3_ARM_v7a.py b/configs/common/O3_ARM_v7a.py
index c971df7fb..2c640badb 100644
--- a/configs/common/O3_ARM_v7a.py
+++ b/configs/common/O3_ARM_v7a.py
@@ -90,7 +90,6 @@ class O3_ARM_v7a_FUP(FUPool):
class O3_ARM_v7a_3(DerivO3CPU):
predType = "tournament"
- localPredictorSize = 64
localCtrBits = 2
localHistoryTableSize = 64
localHistoryBits = 6
diff --git a/src/cpu/inorder/resources/bpred_unit.cc b/src/cpu/inorder/resources/bpred_unit.cc
index 1a458e1d6..eff40566d 100644
--- a/src/cpu/inorder/resources/bpred_unit.cc
+++ b/src/cpu/inorder/resources/bpred_unit.cc
@@ -53,8 +53,7 @@ BPredUnit::BPredUnit(Resource *_res, ThePipeline::Params *params)
params->instShiftAmt);
predictor = Local;
} else if (params->predType == "tournament") {
- tournamentBP = new TournamentBP(params->localPredictorSize,
- params->localCtrBits,
+ tournamentBP = new TournamentBP(params->localCtrBits,
params->localHistoryTableSize,
params->localHistoryBits,
params->globalPredictorSize,
diff --git a/src/cpu/o3/bpred_unit_impl.hh b/src/cpu/o3/bpred_unit_impl.hh
index 7231d8f8c..74fe27a6a 100644
--- a/src/cpu/o3/bpred_unit_impl.hh
+++ b/src/cpu/o3/bpred_unit_impl.hh
@@ -65,8 +65,7 @@ BPredUnit<Impl>::BPredUnit(DerivO3CPUParams *params)
params->instShiftAmt);
predictor = Local;
} else if (params->predType == "tournament") {
- tournamentBP = new TournamentBP(params->localPredictorSize,
- params->localCtrBits,
+ tournamentBP = new TournamentBP(params->localCtrBits,
params->localHistoryTableSize,
params->localHistoryBits,
params->globalPredictorSize,
diff --git a/src/cpu/pred/tournament.cc b/src/cpu/pred/tournament.cc
index ba2b1decb..f36d30ae5 100644
--- a/src/cpu/pred/tournament.cc
+++ b/src/cpu/pred/tournament.cc
@@ -40,11 +40,11 @@
* Authors: Kevin Lim
*/
+#include "base/bitfield.hh"
#include "base/intmath.hh"
#include "cpu/pred/tournament.hh"
-TournamentBP::TournamentBP(unsigned _localPredictorSize,
- unsigned _localCtrBits,
+TournamentBP::TournamentBP(unsigned _localCtrBits,
unsigned _localHistoryTableSize,
unsigned _localHistoryBits,
unsigned _globalPredictorSize,
@@ -53,28 +53,25 @@ TournamentBP::TournamentBP(unsigned _localPredictorSize,
unsigned _choicePredictorSize,
unsigned _choiceCtrBits,
unsigned _instShiftAmt)
- : localPredictorSize(_localPredictorSize),
- localCtrBits(_localCtrBits),
+ : localCtrBits(_localCtrBits),
localHistoryTableSize(_localHistoryTableSize),
localHistoryBits(_localHistoryBits),
globalPredictorSize(_globalPredictorSize),
globalCtrBits(_globalCtrBits),
globalHistoryBits(_globalHistoryBits),
- choicePredictorSize(_globalPredictorSize),
+ choicePredictorSize(_choicePredictorSize),
choiceCtrBits(_choiceCtrBits),
instShiftAmt(_instShiftAmt)
{
- if (!isPowerOf2(localPredictorSize)) {
- fatal("Invalid local predictor size!\n");
- }
+ localPredictorSize = ULL(1) << localHistoryBits;
- //Setup the array of counters for the local predictor
+ //Set up the array of counters for the local predictor
localCtrs.resize(localPredictorSize);
for (int i = 0; i < localPredictorSize; ++i)
localCtrs[i].setBits(localCtrBits);
- localPredictorMask = floorPow2(localPredictorSize) - 1;
+ localPredictorMask = mask(localHistoryBits);
if (!isPowerOf2(localHistoryTableSize)) {
fatal("Invalid local history table size!\n");
@@ -86,9 +83,6 @@ TournamentBP::TournamentBP(unsigned _localPredictorSize,
for (int i = 0; i < localHistoryTableSize; ++i)
localHistoryTable[i] = 0;
- // Setup the local history mask
- localHistoryMask = (1 << localHistoryBits) - 1;
-
if (!isPowerOf2(globalPredictorSize)) {
fatal("Invalid global predictor size!\n");
}
@@ -101,21 +95,45 @@ TournamentBP::TournamentBP(unsigned _localPredictorSize,
//Clear the global history
globalHistory = 0;
- // Setup the global history mask
- globalHistoryMask = (1 << globalHistoryBits) - 1;
+ // Set up the global history mask
+ // this is equivalent to mask(log2(globalPredictorSize)
+ globalHistoryMask = globalPredictorSize - 1;
if (!isPowerOf2(choicePredictorSize)) {
fatal("Invalid choice predictor size!\n");
}
+ // Set up choiceHistoryMask
+ // this is equivalent to mask(log2(choicePredictorSize)
+ choiceHistoryMask = choicePredictorSize - 1;
+
//Setup the array of counters for the choice predictor
choiceCtrs.resize(choicePredictorSize);
for (int i = 0; i < choicePredictorSize; ++i)
choiceCtrs[i].setBits(choiceCtrBits);
- // @todo: Allow for different thresholds between the predictors.
- threshold = (1 << (localCtrBits - 1)) - 1;
+ //Set up historyRegisterMask
+ historyRegisterMask = mask(globalHistoryBits);
+
+ //Check that predictors don't use more bits than they have available
+ if (globalHistoryMask > historyRegisterMask) {
+ fatal("Global predictor too large for global history bits!\n");
+ }
+ if (choiceHistoryMask > historyRegisterMask) {
+ fatal("Choice predictor too large for global history bits!\n");
+ }
+
+ if (globalHistoryMask < historyRegisterMask &&
+ choiceHistoryMask < historyRegisterMask) {
+ inform("More global history bits than required by predictors\n");
+ }
+
+ // Set thresholds for the three predictors' counters
+ // This is equivalent to (2^(Ctr))/2 - 1
+ localThreshold = (ULL(1) << (localCtrBits - 1)) - 1;
+ globalThreshold = (ULL(1) << (globalCtrBits - 1)) - 1;
+ choiceThreshold = (ULL(1) << (choiceCtrBits - 1)) - 1;
}
inline
@@ -131,7 +149,7 @@ void
TournamentBP::updateGlobalHistTaken()
{
globalHistory = (globalHistory << 1) | 1;
- globalHistory = globalHistory & globalHistoryMask;
+ globalHistory = globalHistory & historyRegisterMask;
}
inline
@@ -139,7 +157,7 @@ void
TournamentBP::updateGlobalHistNotTaken()
{
globalHistory = (globalHistory << 1);
- globalHistory = globalHistory & globalHistoryMask;
+ globalHistory = globalHistory & historyRegisterMask;
}
inline
@@ -163,8 +181,8 @@ void
TournamentBP::BTBUpdate(Addr &branch_addr, void * &bp_history)
{
unsigned local_history_idx = calcLocHistIdx(branch_addr);
- //Update Global History to Not Taken
- globalHistory = globalHistory & (globalHistoryMask - 1);
+ //Update Global History to Not Taken (clear LSB)
+ globalHistory &= (historyRegisterMask & ~ULL(1));
//Update Local History to Not Taken
localHistoryTable[local_history_idx] =
localHistoryTable[local_history_idx] & (localPredictorMask & ~ULL(1));
@@ -184,13 +202,15 @@ TournamentBP::lookup(Addr &branch_addr, void * &bp_history)
local_history_idx = calcLocHistIdx(branch_addr);
local_predictor_idx = localHistoryTable[local_history_idx]
& localPredictorMask;
- local_prediction = localCtrs[local_predictor_idx].read() > threshold;
+ local_prediction = localCtrs[local_predictor_idx].read() > localThreshold;
//Lookup in the global predictor to get its branch prediction
- global_prediction = globalCtrs[globalHistory].read() > threshold;
+ global_prediction =
+ globalCtrs[globalHistory & globalHistoryMask].read() > globalThreshold;
//Lookup in the choice predictor to see which one to use
- choice_prediction = choiceCtrs[globalHistory].read() > threshold;
+ choice_prediction =
+ choiceCtrs[globalHistory & choiceHistoryMask].read() > choiceThreshold;
// Create BPHistory and pass it back to be recorded.
BPHistory *history = new BPHistory;
@@ -201,9 +221,7 @@ TournamentBP::lookup(Addr &branch_addr, void * &bp_history)
history->localHistory = local_predictor_idx;
bp_history = (void *)history;
- assert(globalHistory < globalPredictorSize &&
- local_history_idx < localHistoryTableSize &&
- local_predictor_idx < localPredictorSize);
+ assert(local_history_idx < localHistoryTableSize);
// Commented code is for doing speculative update of counters and
// all histories.
@@ -283,10 +301,12 @@ TournamentBP::update(Addr &branch_addr, bool taken, void *bp_history,
// If the local prediction matches the actual outcome,
// decerement the counter. Otherwise increment the
// counter.
+ unsigned choice_predictor_idx =
+ history->globalHistory & choiceHistoryMask;
if (history->localPredTaken == taken) {
- choiceCtrs[history->globalHistory].decrement();
+ choiceCtrs[choice_predictor_idx].decrement();
} else if (history->globalPredTaken == taken) {
- choiceCtrs[history->globalHistory].increment();
+ choiceCtrs[choice_predictor_idx].increment();
}
}
@@ -295,13 +315,15 @@ TournamentBP::update(Addr &branch_addr, bool taken, void *bp_history,
// resolution of the branch. Global history is updated
// speculatively and restored upon squash() calls, so it does not
// need to be updated.
+ unsigned global_predictor_idx =
+ history->globalHistory & globalHistoryMask;
if (taken) {
- globalCtrs[history->globalHistory].increment();
+ globalCtrs[global_predictor_idx].increment();
if (old_local_pred_valid) {
localCtrs[old_local_pred_index].increment();
}
} else {
- globalCtrs[history->globalHistory].decrement();
+ globalCtrs[global_predictor_idx].decrement();
if (old_local_pred_valid) {
localCtrs[old_local_pred_index].decrement();
}
@@ -310,14 +332,14 @@ TournamentBP::update(Addr &branch_addr, bool taken, void *bp_history,
if (squashed) {
if (taken) {
globalHistory = (history->globalHistory << 1) | 1;
- globalHistory = globalHistory & globalHistoryMask;
+ globalHistory = globalHistory & historyRegisterMask;
if (old_local_pred_valid) {
localHistoryTable[local_history_idx] =
(history->localHistory << 1) | 1;
}
} else {
globalHistory = (history->globalHistory << 1);
- globalHistory = globalHistory & globalHistoryMask;
+ globalHistory = globalHistory & historyRegisterMask;
if (old_local_pred_valid) {
localHistoryTable[local_history_idx] =
history->localHistory << 1;
@@ -330,9 +352,7 @@ TournamentBP::update(Addr &branch_addr, bool taken, void *bp_history,
}
- assert(globalHistory < globalPredictorSize &&
- local_history_idx < localHistoryTableSize &&
- local_predictor_idx < localPredictorSize);
+ assert(local_history_idx < localHistoryTableSize);
}
diff --git a/src/cpu/pred/tournament.hh b/src/cpu/pred/tournament.hh
index f9df2a61d..35cfd8455 100644
--- a/src/cpu/pred/tournament.hh
+++ b/src/cpu/pred/tournament.hh
@@ -63,8 +63,7 @@ class TournamentBP
/**
* Default branch predictor constructor.
*/
- TournamentBP(unsigned localPredictorSize,
- unsigned localCtrBits,
+ TournamentBP(unsigned localCtrBits,
unsigned localHistoryTableSize,
unsigned localHistoryBits,
unsigned globalPredictorSize,
@@ -181,10 +180,10 @@ class TournamentBP
/** Local counters. */
std::vector<SatCounter> localCtrs;
- /** Size of the local predictor. */
+ /** Number of counters in the local predictor. */
unsigned localPredictorSize;
- /** Mask to get the proper index bits into the predictor. */
+ /** Mask to truncate values stored in the local history table. */
unsigned localPredictorMask;
/** Number of bits of the local predictor's counters. */
@@ -193,42 +192,49 @@ class TournamentBP
/** Array of local history table entries. */
std::vector<unsigned> localHistoryTable;
- /** Size of the local history table. */
+ /** Number of entries in the local history table. */
unsigned localHistoryTableSize;
- /** Number of bits for each entry of the local history table.
- * @todo Doesn't this come from the size of the local predictor?
- */
+ /** Number of bits for each entry of the local history table. */
unsigned localHistoryBits;
- /** Mask to get the proper local history. */
- unsigned localHistoryMask;
-
/** Array of counters that make up the global predictor. */
std::vector<SatCounter> globalCtrs;
- /** Size of the global predictor. */
+ /** Number of entries in the global predictor. */
unsigned globalPredictorSize;
/** Number of bits of the global predictor's counters. */
unsigned globalCtrBits;
- /** Global history register. */
+ /** Global history register. Contains as much history as specified by
+ * globalHistoryBits. Actual number of bits used is determined by
+ * globalHistoryMask and choiceHistoryMask. */
unsigned globalHistory;
- /** Number of bits for the global history. */
+ /** Number of bits for the global history. Determines maximum number of
+ entries in global and choice predictor tables. */
unsigned globalHistoryBits;
- /** Mask to get the proper global history. */
+ /** Mask to apply to globalHistory to access global history table.
+ * Based on globalPredictorSize.*/
unsigned globalHistoryMask;
+ /** Mask to apply to globalHistory to access choice history table.
+ * Based on choicePredictorSize.*/
+ unsigned choiceHistoryMask;
+
+ /** Mask to control how much history is stored. All of it might not be
+ * used. */
+ unsigned historyRegisterMask;
+
/** Array of counters that make up the choice predictor. */
std::vector<SatCounter> choiceCtrs;
- /** Size of the choice predictor (identical to the global predictor). */
+ /** Number of entries in the choice predictor. */
unsigned choicePredictorSize;
- /** Number of bits of the choice predictor's counters. */
+ /** Number of bits in the choice predictor's counters. */
unsigned choiceCtrBits;
/** Number of bits to shift the instruction over to get rid of the word
@@ -236,10 +242,12 @@ class TournamentBP
*/
unsigned instShiftAmt;
- /** Threshold for the counter value; above the threshold is taken,
+ /** Thresholds for the counter value; above the threshold is taken,
* equal to or below the threshold is not taken.
*/
- unsigned threshold;
+ unsigned localThreshold;
+ unsigned globalThreshold;
+ unsigned choiceThreshold;
};
#endif // __CPU_O3_TOURNAMENT_PRED_HH__