diff -r daac35264bb0 -r a2d5d47de2bf configs/common/O3_ARM_v7a.py --- a/configs/common/O3_ARM_v7a.py Mon Oct 29 16:27:48 2012 +0000 +++ b/configs/common/O3_ARM_v7a.py Tue Oct 30 15:33:59 2012 +0000 @@ -90,7 +90,6 @@ class O3_ARM_v7a_3(DerivO3CPU): predType = "tournament" - localPredictorSize = 64 localCtrBits = 2 localHistoryTableSize = 64 localHistoryBits = 6 diff -r daac35264bb0 -r a2d5d47de2bf src/cpu/inorder/resources/bpred_unit.cc --- a/src/cpu/inorder/resources/bpred_unit.cc Mon Oct 29 16:27:48 2012 +0000 +++ b/src/cpu/inorder/resources/bpred_unit.cc Tue Oct 30 15:33:59 2012 +0000 @@ -53,8 +53,7 @@ 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 -r daac35264bb0 -r a2d5d47de2bf src/cpu/o3/bpred_unit_impl.hh --- a/src/cpu/o3/bpred_unit_impl.hh Mon Oct 29 16:27:48 2012 +0000 +++ b/src/cpu/o3/bpred_unit_impl.hh Tue Oct 30 15:33:59 2012 +0000 @@ -65,8 +65,7 @@ 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 -r daac35264bb0 -r a2d5d47de2bf src/cpu/pred/tournament.hh --- a/src/cpu/pred/tournament.hh Mon Oct 29 16:27:48 2012 +0000 +++ b/src/cpu/pred/tournament.hh Tue Oct 30 15:33:59 2012 +0000 @@ -63,8 +63,7 @@ /** * Default branch predictor constructor. */ - TournamentBP(unsigned localPredictorSize, - unsigned localCtrBits, + TournamentBP(unsigned localCtrBits, unsigned localHistoryTableSize, unsigned localHistoryBits, unsigned globalPredictorSize, @@ -213,15 +212,27 @@ /** 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 choiceCtrs; @@ -236,10 +247,12 @@ */ 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__ diff -r daac35264bb0 -r a2d5d47de2bf src/cpu/pred/tournament.cc --- a/src/cpu/pred/tournament.cc Mon Oct 29 16:27:48 2012 +0000 +++ b/src/cpu/pred/tournament.cc Tue Oct 30 15:33:59 2012 +0000 @@ -43,8 +43,7 @@ #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,8 +52,7 @@ unsigned _choicePredictorSize, unsigned _choiceCtrBits, unsigned _instShiftAmt) - : localPredictorSize(_localPredictorSize), - localCtrBits(_localCtrBits), + : localCtrBits(_localCtrBits), localHistoryTableSize(_localHistoryTableSize), localHistoryBits(_localHistoryBits), globalPredictorSize(_globalPredictorSize), @@ -64,9 +62,7 @@ choiceCtrBits(_choiceCtrBits), instShiftAmt(_instShiftAmt) { - if (!isPowerOf2(localPredictorSize)) { - fatal("Invalid local predictor size!\n"); - } + localPredictorSize = 1 << localHistoryBits; //Setup the array of counters for the local predictor localCtrs.resize(localPredictorSize); @@ -102,20 +98,41 @@ //Clear the global history globalHistory = 0; // Setup the global history mask - globalHistoryMask = (1 << globalHistoryBits) - 1; + globalHistoryMask = (1 << floorLog2(globalPredictorSize)) - 1; if (!isPowerOf2(choicePredictorSize)) { fatal("Invalid choice predictor size!\n"); } + //Set up choiceHistoryMask + choiceHistoryMask = (1 << floorLog2(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 = (1 << globalHistoryBits) - 1; + + //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 + localThreshold = (1 << (localCtrBits - 1)) - 1; + globalThreshold = (1 << (globalCtrBits - 1)) - 1; + choiceThreshold = (1 << (choiceCtrBits - 1)) - 1; } inline @@ -131,7 +148,7 @@ TournamentBP::updateGlobalHistTaken() { globalHistory = (globalHistory << 1) | 1; - globalHistory = globalHistory & globalHistoryMask; + globalHistory = globalHistory & historyRegisterMask; } inline @@ -139,7 +156,7 @@ TournamentBP::updateGlobalHistNotTaken() { globalHistory = (globalHistory << 1); - globalHistory = globalHistory & globalHistoryMask; + globalHistory = globalHistory & historyRegisterMask; } inline @@ -164,7 +181,7 @@ { unsigned local_history_idx = calcLocHistIdx(branch_addr); //Update Global History to Not Taken - globalHistory = globalHistory & (globalHistoryMask - 1); + globalHistory = globalHistory & (historyRegisterMask - 1); //Update Local History to Not Taken localHistoryTable[local_history_idx] = localHistoryTable[local_history_idx] & (localPredictorMask - 1); @@ -184,13 +201,15 @@ 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 +220,7 @@ 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. @@ -277,10 +294,12 @@ // 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(); } } @@ -289,13 +308,15 @@ // 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_index != invalidPredictorIndex) { localCtrs[old_local_pred_index].increment(); } } else { - globalCtrs[history->globalHistory].decrement(); + globalCtrs[global_predictor_idx].decrement(); if (old_local_pred_index != invalidPredictorIndex) { localCtrs[old_local_pred_index].decrement(); } @@ -304,14 +325,14 @@ if (squashed) { if (taken) { globalHistory = (history->globalHistory << 1) | 1; - globalHistory = globalHistory & globalHistoryMask; + globalHistory = globalHistory & historyRegisterMask; if (old_local_pred_index != invalidPredictorIndex) { localHistoryTable[old_local_pred_index] = (history->localHistory << 1) | 1; } } else { globalHistory = (history->globalHistory << 1); - globalHistory = globalHistory & globalHistoryMask; + globalHistory = globalHistory & historyRegisterMask; if (old_local_pred_index != invalidPredictorIndex) { localHistoryTable[old_local_pred_index] = history->localHistory << 1; @@ -324,9 +345,7 @@ } - assert(globalHistory < globalPredictorSize && - local_history_idx < localHistoryTableSize && - local_predictor_idx < localPredictorSize); + assert(local_history_idx < localHistoryTableSize); }