src/Sim/Predictor/BPred/BPred.cpp

説明を見る。
00001 // 
00002 // Copyright (c) 2005-2008 Kenichi Watanabe.
00003 // Copyright (c) 2005-2008 Yasuhiro Watari.
00004 // Copyright (c) 2005-2008 Hironori Ichibayashi.
00005 // Copyright (c) 2008-2009 Kazuo Horio.
00006 // Copyright (c) 2009-2013 Naruki Kurata.
00007 // Copyright (c) 2005-2013 Ryota Shioya.
00008 // Copyright (c) 2005-2013 Masahiro Goshima.
00009 // 
00010 // This software is provided 'as-is', without any express or implied
00011 // warranty. In no event will the authors be held liable for any damages
00012 // arising from the use of this software.
00013 // 
00014 // Permission is granted to anyone to use this software for any purpose,
00015 // including commercial applications, and to alter it and redistribute it
00016 // freely, subject to the following restrictions:
00017 // 
00018 // 1. The origin of this software must not be misrepresented; you must not
00019 // claim that you wrote the original software. If you use this software
00020 // in a product, an acknowledgment in the product documentation would be
00021 // appreciated but is not required.
00022 // 
00023 // 2. Altered source versions must be plainly marked as such, and must not be
00024 // misrepresented as being the original software.
00025 // 
00026 // 3. This notice may not be removed or altered from any source
00027 // distribution.
00028 // 
00029 // 
00030 
00031 
00032 #include <pch.h>
00033 
00034 #include "Sim/Predictor/BPred/BPred.h"
00035 
00036 #include "Utility/RuntimeError.h"
00037 #include "Interface/OpClass.h"
00038 #include "Sim/Dumper/Dumper.h"
00039 #include "Sim/ISAInfo.h"
00040 #include "Sim/Foundation/SimPC.h"
00041 #include "Sim/Core/Core.h"
00042 #include "Sim/Op/Op.h"
00043 
00044 #include "Sim/Foundation/Hook/Hook.h"
00045 #include "Sim/Foundation/Hook/HookUtil.h"
00046 
00047 #include "Sim/Predictor/BPred/PHT.h"
00048 #include "Sim/Predictor/BPred/DirPredIF.h"
00049 #include "Sim/Predictor/BPred/GlobalHistory.h"
00050 #include "Sim/Predictor/BPred/RAS.h"
00051 #include "Sim/Recoverer/Recoverer.h"
00052 #include "Sim/InorderList/InorderList.h"
00053 #include "Sim/Thread/Thread.h"
00054 #include "Sim/System/ForwardEmulator.h"
00055 
00056 namespace Onikiri 
00057 {
00058     HookPoint<BPred> BPred::s_branchPredictionMissHook;
00059 };
00060 
00061 
00062 using namespace Onikiri;
00063 using namespace std;
00064 
00065 
00066 BPred::Statistics::Statistics()
00067 {
00068     numHit  = 0;
00069     numMiss = 0;
00070 }
00071 
00072 void BPred::Statistics::SetName( const String& name )
00073 {
00074     this->name = name;
00075 }
00076 
00077 
00078 BPred::BPred()
00079 {
00080     m_dirPred = 0;
00081     m_btb = 0;
00082     m_core = 0;
00083     m_fwdEmulator = 0;
00084     m_mode = SM_SIMULATION;
00085     m_perfect = false;
00086 
00087     BranchTypeUtility util;
00088     m_statistics.resize( util.GetTypeCount() );
00089     for( size_t i = 0; i < util.GetTypeCount(); i++){
00090         m_statistics[i].SetName( util.GetTypeName(i) );
00091     }
00092     m_totalStatistics.SetName( "All" );
00093 }
00094 
00095 BPred::~BPred()
00096 {
00097     ReleaseParam();
00098 }
00099 
00100 // 
00101 void BPred::Initialize( InitPhase phase )
00102 {
00103     if( phase == INIT_PRE_CONNECTION ){
00104         LoadParam();
00105     }
00106     else if( phase == INIT_POST_CONNECTION ){
00107 
00108         // oZbg`FbN
00109         CheckNodeInitialized( "dirPred", m_dirPred );
00110         CheckNodeInitialized( "btb",  m_btb );
00111         CheckNodeInitialized( "ras",  m_ras );
00112         CheckNodeInitialized( "core", m_core );
00113         CheckNodeInitialized( "forwardEmulator", m_fwdEmulator );
00114 
00115         if( !m_fwdEmulator->IsEnabled() ){
00116             THROW_RUNTIME_ERROR(
00117                 "A perfect memory dependency predictor requires that a forawrd emulator is enabled." 
00118             );
00119         }
00120 
00121         m_btbPredTable.Resize( *m_core->GetOpArray() );
00122     }
00123 }
00124 
00125 // <TODO> {CtFb`O[vtFb`O[v\
00126 
00127 // op A fetch  PC \
00128 PC BPred::Predict( OpIterator op, PC predIndexPC )
00129 {
00130     if( m_perfect && m_mode == SM_SIMULATION ){
00131         // Forward emulator can work in a simulation mode only.
00132         const OpStateIF* result = m_fwdEmulator->GetExecutionResult( op );
00133         if( !result ){
00134             THROW_RUNTIME_ERROR( "Pre-executed result cannot be retrieved from a forward emulator." );
00135         }
00136         return
00137             result->GetTaken() ? result->GetTakenPC() : NextPC( result->GetPC() );
00138     }
00139 
00140 
00141     SimPC pc = op->GetPC();
00142     BTBPredict btbPred = m_btb->Predict(predIndexPC);
00143     bool btbHit     = btbPred.hit;
00144 
00145     m_btbPredTable[op] = btbPred;
00146 
00147     // BTBqbgC\iXVjs
00148     if(!btbHit)
00149         return pc.Next();
00150 
00151 
00152     PC branchTarget = btbPred.target;
00153 
00154     // 
00155     bool predTaken  = btbPred.dirPredict ? m_dirPred->Predict(op, predIndexPC) : true;
00156 
00157     switch(btbPred.type){
00158     case BT_NON:
00159         ASSERT(0, "BT_NON is invalid.");
00160         return pc.Next();
00161 
00162     case BT_CONDITIONAL:
00163         // taken / not taken \APC
00164         // not taken \CopPC
00165         return predTaken ? branchTarget : pc.Next();        
00166 
00167     case BT_UNCONDITIONAL:
00168         //  BTB \
00169         return branchTarget;
00170 
00171     case BT_CALL:
00172         // call  RAS  push ABTB \
00173         // (CNgPushs
00174         m_ras[op->GetLocalTID()]->Push(pc);
00175         return branchTarget;
00176 
00177     case BT_RETURN:
00178         // return  RAS \ 
00179         return m_ras[op->GetLocalTID()]->Pop();
00180 
00181     case BT_CONDITIONAL_RETURN:
00182         // t^[DirPredTakenPop        
00183         // not taken PC
00184         return predTaken ? m_ras[op->GetLocalTID()]->Pop() : pc.Next();
00185 
00186     case BT_END:
00187         break;
00188     }
00189 
00190     // B
00191     THROW_RUNTIME_ERROR("reached end of Bpred::Predict\n");
00192 
00193     return pc.Next();   // warning 
00194 }
00195 
00196 // op タsI
00197 void BPred::Finished( OpIterator op )
00198 {
00199     if( m_perfect ){
00200         return;
00201     }
00202 
00203     const OpClass& opClass = op->GetOpClass();
00204 
00205     // 
00206     if( !opClass.IsBranch() ) {
00207         return;
00208     }
00209 
00210     // Detect branch miss prediction and recovery if prediction is incorrect.
00211     RecoveryFromBPredMiss( op );
00212 
00213     // \タsm
00214     // i\BTBqbg
00215     if( opClass.IsConditionalBranch() && m_btbPredTable[op].hit ){
00216         m_dirPred->Finished( op );
00217     }
00218 }
00219 
00220 // op ^CA
00221 void BPred::Commit( OpIterator op )
00222 {
00223     if( m_perfect && m_mode != SM_SIMULATION ){
00224         return;
00225     }
00226 
00227     const OpClass& opClass = op->GetOpClass();
00228     if( !opClass.IsBranch() )
00229         return;
00230 
00231     bool conditional = opClass.IsConditionalBranch();
00232     
00233     if( !m_perfect ){
00234         // BTBXV
00235         const BTBPredict& predict = m_btbPredTable[op];
00236         m_btb->Update( op, predict );
00237 
00238         // \^CAm
00239         // i\BTBqbg
00240         if( conditional && predict.hit ){
00241             m_dirPred->Retired( op );
00242         }
00243     }
00244 
00245     // qbg
00246     PC pcTaken  = op->GetTakenPC();
00247     PC pcPred   = op->GetPredPC();
00248     PC pcNext   = NextPC( op->GetPC() );
00249     bool taken  = conditional ? op->GetTaken() : true;
00250     PC pcResult = taken ? pcTaken : pcNext;
00251 
00252     BranchTypeUtility util;
00253     BranchType type = util.OpClassToBranchType( opClass );
00254     if( pcPred == pcResult ){
00255         m_statistics[type].numHit++;
00256         m_totalStatistics.numHit++;
00257     }
00258     else{
00259         m_statistics[type].numMiss++;
00260         m_totalStatistics.numMiss++;
00261     }
00262 
00263 }
00264 
00265 // Detect branch miss prediction and recovery if prediction is incorrect.
00266 void BPred::RecoveryFromBPredMiss( OpIterator branch )
00267 {
00268     // Recovery is not necessary when the simulator is in an in-order mode.
00269     if( m_mode != PhysicalResourceNode::SM_SIMULATION ){
00270         return;
00271     }
00272 
00273     // If a perfect mode is enabled, prediction results are always correct and 
00274     // there is not nothing to do.
00275     if( IsPerfect() ){
00276         return;
00277     }
00278 
00279     if( branch->GetPredPC() != branch->GetNextPC() ) {
00280         // A branch prediction result is incorrect and recovery from an incorrect path.
00281         g_dumper.Dump( DS_BRANCH_PREDICTION_MISS, branch );
00282         HOOK_SECTION_OP( s_branchPredictionMissHook, branch )
00283         {
00284             Recoverer* recoverer = branch->GetThread()->GetRecoverer();
00285             recoverer->RecoverBPredMiss( branch );
00286         }
00287     }
00288 }

Onikiri2に対してTue Jun 18 14:34:25 2013に生成されました。  doxygen 1.4.7