diff -r daac35264bb0 -r 55cf0b4cddc8 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 Mon Oct 29 16:28:13 2012 +0000 @@ -213,15 +213,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 +248,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 55cf0b4cddc8 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 Mon Oct 29 16:28:13 2012 +0000 @@ -89,6 +89,14 @@ // Setup the local history mask localHistoryMask = (1 << localHistoryBits) - 1; + //@TODO: one of localPredictorSize and localHistoryBits is redundant + if (floorLog2(localPredictorSize) > localHistoryBits) { + inform("Local predictor larger than history bits can address\n"); + } + if (floorLog2(localPredictorSize) < localHistoryBits) { + inform("More local history bits than required by predictor table\n"); + } + if (!isPowerOf2(globalPredictorSize)) { fatal("Invalid global predictor size!\n"); } @@ -102,20 +110,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 +160,7 @@ TournamentBP::updateGlobalHistTaken() { globalHistory = (globalHistory << 1) | 1; - globalHistory = globalHistory & globalHistoryMask; + globalHistory = globalHistory & historyRegisterMask; } inline @@ -139,7 +168,7 @@ TournamentBP::updateGlobalHistNotTaken() { globalHistory = (globalHistory << 1); - globalHistory = globalHistory & globalHistoryMask; + globalHistory = globalHistory & historyRegisterMask; } inline @@ -164,7 +193,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 +213,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,8 +232,7 @@ history->localHistory = local_predictor_idx; bp_history = (void *)history; - assert(globalHistory < globalPredictorSize && - local_history_idx < localHistoryTableSize && + assert(local_history_idx < localHistoryTableSize && local_predictor_idx < localPredictorSize); // Commented code is for doing speculative update of counters and @@ -278,9 +308,11 @@ // decerement the counter. Otherwise increment the // counter. if (history->localPredTaken == taken) { - choiceCtrs[history->globalHistory].decrement(); + choiceCtrs[(history->globalHistory) & choiceHistoryMask]. + decrement(); } else if (history->globalPredTaken == taken) { - choiceCtrs[history->globalHistory].increment(); + choiceCtrs[(history->globalHistory) & choiceHistoryMask]. + increment(); } } @@ -290,12 +322,14 @@ // speculatively and restored upon squash() calls, so it does not // need to be updated. if (taken) { - globalCtrs[history->globalHistory].increment(); + globalCtrs[(history->globalHistory) & globalHistoryMask]. + increment(); if (old_local_pred_index != invalidPredictorIndex) { localCtrs[old_local_pred_index].increment(); } } else { - globalCtrs[history->globalHistory].decrement(); + globalCtrs[(history->globalHistory) & globalHistoryMask]. + decrement(); if (old_local_pred_index != invalidPredictorIndex) { localCtrs[old_local_pred_index].decrement(); } @@ -304,14 +338,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,8 +358,7 @@ } - assert(globalHistory < globalPredictorSize && - local_history_idx < localHistoryTableSize && + assert(local_history_idx < localHistoryTableSize && local_predictor_idx < localPredictorSize);