tournament_pred.cc

来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· CC 代码 · 共 298 行

CC
298
字号
/* * Copyright (c) 2004, 2005, 2006 * The Regents of The University of Michigan * All Rights Reserved * * This code is part of the M5 simulator. * * Permission is granted to use, copy, create derivative works and * redistribute this software and such derivative works for any * purpose, so long as the copyright notice above, this grant of * permission, and the disclaimer below appear in all copies made; and * so long as the name of The University of Michigan is not used in * any advertising or publicity pertaining to the use or distribution * of this software without specific, written prior authorization. * * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE * UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND * WITHOUT WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER * EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE * LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, SPECIAL, INDIRECT, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM * ARISING OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH * DAMAGES. * * Authors: Kevin T. Lim */#include "base/intmath.hh"#include "cpu/o3/tournament_pred.hh"TournamentBP::TournamentBP(unsigned _localPredictorSize,                           unsigned _localCtrBits,                           unsigned _localHistoryTableSize,                           unsigned _localHistoryBits,                           unsigned _globalPredictorSize,                           unsigned _globalCtrBits,                           unsigned _globalHistoryBits,                           unsigned _choicePredictorSize,                           unsigned _choiceCtrBits,                           unsigned _instShiftAmt)    : localPredictorSize(_localPredictorSize),      localCtrBits(_localCtrBits),      localHistoryTableSize(_localHistoryTableSize),      localHistoryBits(_localHistoryBits),      globalPredictorSize(_globalPredictorSize),      globalCtrBits(_globalCtrBits),      globalHistoryBits(_globalHistoryBits),      choicePredictorSize(_globalPredictorSize),      choiceCtrBits(_choiceCtrBits),      instShiftAmt(_instShiftAmt){    if (!isPowerOf2(localPredictorSize)) {        fatal("Invalid local predictor size!\n");    }    //Setup 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;    if (!isPowerOf2(localHistoryTableSize)) {        fatal("Invalid local history table size!\n");    }    //Setup the history table for the local table    localHistoryTable.resize(localHistoryTableSize);    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");    }    //Setup the array of counters for the global predictor    globalCtrs.resize(globalPredictorSize);    for (int i = 0; i < globalPredictorSize; ++i)        globalCtrs[i].setBits(globalCtrBits);    //Clear the global history    globalHistory = 0;    // Setup the global history mask    globalHistoryMask = (1 << globalHistoryBits) - 1;    if (!isPowerOf2(choicePredictorSize)) {        fatal("Invalid choice predictor size!\n");    }    //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;    threshold = threshold / 2;}inlineunsignedTournamentBP::calcLocHistIdx(Addr &branch_addr){    // Get low order bits after removing instruction offset.    return (branch_addr >> instShiftAmt) & (localHistoryTableSize - 1);}inlinevoidTournamentBP::updateGlobalHistTaken(){    globalHistory = (globalHistory << 1) | 1;    globalHistory = globalHistory & globalHistoryMask;}inlinevoidTournamentBP::updateGlobalHistNotTaken(){    globalHistory = (globalHistory << 1);    globalHistory = globalHistory & globalHistoryMask;}inlinevoidTournamentBP::updateLocalHistTaken(unsigned local_history_idx){    localHistoryTable[local_history_idx] =        (localHistoryTable[local_history_idx] << 1) | 1;}inlinevoidTournamentBP::updateLocalHistNotTaken(unsigned local_history_idx){    localHistoryTable[local_history_idx] =        (localHistoryTable[local_history_idx] << 1);}boolTournamentBP::lookup(Addr &branch_addr, void * &bp_history){    bool local_prediction;    unsigned local_history_idx;    unsigned local_predictor_idx;    bool global_prediction;    bool choice_prediction;    //Lookup in the local predictor to get its branch prediction    local_history_idx = calcLocHistIdx(branch_addr);    local_predictor_idx = localHistoryTable[local_history_idx]        & localPredictorMask;    local_prediction = localCtrs[local_predictor_idx].read() > threshold;    //Lookup in the global predictor to get its branch prediction    global_prediction = globalCtrs[globalHistory].read() > threshold;    //Lookup in the choice predictor to see which one to use    choice_prediction = choiceCtrs[globalHistory].read() > threshold;    // Create BPHistory and pass it back to be recorded.    BPHistory *history = new BPHistory;    history->globalHistory = globalHistory;    history->localPredTaken = local_prediction;    history->globalPredTaken = global_prediction;    history->globalUsed = choice_prediction;    bp_history = (void *)history;    assert(globalHistory < globalPredictorSize &&           local_history_idx < localHistoryTableSize &&           local_predictor_idx < localPredictorSize);    // Commented code is for doing speculative update of counters and    // all histories.    if (choice_prediction) {        if (global_prediction) {//            updateHistoriesTaken(local_history_idx);//            globalCtrs[globalHistory].increment();//            localCtrs[local_history_idx].increment();            updateGlobalHistTaken();            return true;        } else {//            updateHistoriesNotTaken(local_history_idx);//            globalCtrs[globalHistory].decrement();//            localCtrs[local_history_idx].decrement();            updateGlobalHistNotTaken();            return false;        }    } else {        if (local_prediction) {//            updateHistoriesTaken(local_history_idx);//            globalCtrs[globalHistory].increment();//            localCtrs[local_history_idx].increment();            updateGlobalHistTaken();            return true;        } else {//            updateHistoriesNotTaken(local_history_idx);//            globalCtrs[globalHistory].decrement();//            localCtrs[local_history_idx].decrement();            updateGlobalHistNotTaken();            return false;        }    }}voidTournamentBP::uncondBr(void * &bp_history){    // Create BPHistory and pass it back to be recorded.    BPHistory *history = new BPHistory;    history->globalHistory = globalHistory;    history->localPredTaken = true;    history->globalPredTaken = true;    bp_history = static_cast<void *>(history);    updateGlobalHistTaken();}voidTournamentBP::update(Addr &branch_addr, bool taken, void *bp_history){    unsigned local_history_idx;    unsigned local_predictor_idx;    unsigned local_predictor_hist;    // Get the local predictor's current prediction    local_history_idx = calcLocHistIdx(branch_addr);    local_predictor_hist = localHistoryTable[local_history_idx];    local_predictor_idx = local_predictor_hist & localPredictorMask;    // Update the choice predictor to tell it which one was correct if    // there was a prediction.    if (bp_history) {        BPHistory *history = static_cast<BPHistory *>(bp_history);        if (history->localPredTaken != history->globalPredTaken) {            // If the local prediction matches the actual outcome,            // decerement the counter.  Otherwise increment the            // counter.            if (history->localPredTaken == taken) {                choiceCtrs[globalHistory].decrement();            } else if (history->globalPredTaken == taken){                choiceCtrs[globalHistory].increment();            }        }        // We're done with this history, now delete it.        delete history;    }    assert(globalHistory < globalPredictorSize &&           local_history_idx < localHistoryTableSize &&           local_predictor_idx < localPredictorSize);    // Update the counters and local history with the proper    // resolution of the branch.  Global history is updated    // speculatively and restored upon squash() calls, so it does not    // need to be updated.    if (taken) {        localCtrs[local_predictor_idx].increment();        globalCtrs[globalHistory].increment();        updateLocalHistTaken(local_history_idx);    } else {        localCtrs[local_predictor_idx].decrement();        globalCtrs[globalHistory].decrement();        updateLocalHistNotTaken(local_history_idx);    }}voidTournamentBP::squash(void *bp_history){    BPHistory *history = static_cast<BPHistory *>(bp_history);    // Restore global history to state prior to this branch.    globalHistory = history->globalHistory;    // Delete this BPHistory now that we're done with it.    delete history;}#ifdef DEBUGintTournamentBP::BPHistory::newCount = 0;#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?