src/Sim/System/InorderSystem/InorderSystem.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 #include "Sim/System/InorderSystem/InorderSystem.h"
00034 #include "Sim/Dumper/Dumper.h"
00035 
00036 #include "Sim/Predictor/DepPred/RegDepPred/RegDepPredIF.h"
00037 #include "Sim/Predictor/BPred/BPred.h"
00038 #include "Sim/Predictor/LatPred/LatPredResult.h"
00039 #include "Sim/InorderList/InorderList.h"
00040 #include "Sim/Register/RegisterFile.h"
00041 #include "Sim/Memory/Cache/Cache.h"
00042 #include "Sim/Memory/Cache/CacheSystem.h"
00043 #include "Sim/Op/Op.h"
00044 #include "Sim/Op/OpInitArgs.h"
00045 #include "Sim/Pipeline/Fetcher/Fetcher.h"
00046 #include "Sim/Pipeline/Dispatcher/Steerer/OpCodeSteerer.h"
00047 #include "Sim/Pipeline/Renamer/Renamer.h"
00048 #include "Sim/Pipeline/Scheduler/Scheduler.h"
00049 #include "Sim/Predictor/HitMissPred/HitMissPredIF.h"
00050 #include "Sim/Predictor/LatPred/LatPred.h"
00051 #include "Sim/Dependency/PhyReg/PhyReg.h"
00052 #include "Sim/Memory/MemOrderManager/MemOrderManager.h"
00053 
00054 using namespace std;
00055 using namespace boost;
00056 using namespace Onikiri;
00057 
00058 //
00059 // --- Run
00060 //
00061 
00062 InorderSystem::InorderSystem()
00063 {
00064     m_enableBPred = false;
00065     m_enableHMPred = false;
00066     m_enableCache = false;
00067 }
00068 
00069 InorderSystem::~InorderSystem()
00070 {}
00071 
00072 void InorderSystem::Run( SystemContext* context )
00073 {
00074     m_enableBPred = context->inorderParam.enableBPred;
00075     m_enableHMPred = context->inorderParam.enableHMPred;
00076     m_enableCache = context->inorderParam.enableCache;
00077 
00078     const s64 numInsns = context->executionInsns;
00079     for( int i = 0; i < context->threads.GetSize(); i++ ){
00080         g_dumper.SetCurrentCycle( context->threads[i], 0 );
00081     }
00082 
00083     int processCount = context->emulator->GetProcessCount();
00084 
00085     // WX^
00086     ArchitectureStateList& archStateList = context->architectureStateList;
00087 
00088     EmulatorIF* emulator = context->emulator;
00089     s64 totalInsnCount = 0;
00090     vector<s64> insnCount;
00091     u64 opCount = 0;
00092     int curPID = 0;
00093     int terminateProcesses = 0;
00094 
00095     insnCount.resize( processCount, 0 );
00096 
00097     while( totalInsnCount < numInsns ){
00098         // Decide a thread executed in this iteration.
00099         PC& curThreadPC = archStateList[curPID].pc;
00100         curPID = (curPID + 1);  // Round robin
00101         if( curPID >= processCount ){
00102             curPID -= processCount;
00103         }
00104 
00105         std::pair<OpInfo**, int> ops = emulator->GetOp(curThreadPC);
00106 
00107         OpInfo** opInfoArray = ops.first;
00108         int infoCount        = ops.second;
00109 
00110         // inorder タs info tFb`vOI
00111         if( opInfoArray == 0 || opInfoArray[0] == 0 ) {
00112             terminateProcesses++;
00113             if(terminateProcesses >= processCount){
00114                 break;
00115             }
00116             else{
00117                 continue;
00118             }
00119         }
00120 
00121         totalInsnCount++;
00122         insnCount[curPID]++;
00123 
00124         Thread* thread = context->threads[ curThreadPC.tid ];
00125         Core*   core = thread->GetCore();
00126         InorderList* inorderList = thread->GetInorderList();
00127         BPred* bPred = core->GetFetcher()->GetBPred();
00128         RegDepPredIF* regDepPred = thread->GetRegDepPred();
00129         MemOrderManager* memOrderManager = thread->GetMemOrderManager();
00130         HitMissPredIF* hmPred = core->GetLatPred()->GetHitMissPred();
00131         CacheSystem* cacheSystem = core->GetCacheSystem();
00132         Cache* cache = cacheSystem->GetFirstLevelDataCache();
00133         MemIF* memImage = emulator->GetMemImage();
00134         Renamer* renamer = core->GetRenamer();
00135         DispatchSteererIF* steerer = renamer->GetSteerer();
00136 
00137         // opInfoArray Sタs
00138         for(int infoIndex = 0; infoIndex < infoCount; ++infoIndex){
00139             OpInfo* opInfo  = opInfoArray[infoIndex];
00140             OpClass opClass = opInfo->GetOpClass();
00141 
00142             OpInitArgs args = 
00143             {
00144                 // Todo: thread op count
00145                 &curThreadPC, 
00146                 opInfo,
00147                 infoIndex,
00148                 opCount,
00149                 opCount,
00150                 opCount,
00151                 thread->GetCore(), 
00152                 thread
00153             };
00154             
00155             OpIterator op = inorderList->ConstructOp( args );
00156             
00157             op->SetTakenPC( Addr(curThreadPC.pid, curThreadPC.tid, curThreadPC.address+4) );
00158 
00159             // \[XIyh
00160             regDepPred->Resolve(op);
00161 
00162             // fXeBl[VWX^
00163             regDepPred->Allocate(op);
00164 
00165             // tFb`
00166             if( opClass.IsLoad() ) {
00167                 memOrderManager->Allocate(op);
00168             }
00169 
00170             // tFb`
00171             if( m_enableBPred && opClass.IsBranch() ) {
00172                 PC predPC = bPred->Predict(op, op->GetPC());
00173 
00174                 // BTB/RAS Gg CPID
00175                 predPC.pid = op->GetPC().pid;
00176                 predPC.tid = op->GetPC().tid;
00177 
00178                 op->SetPredPC(predPC);
00179             }
00180 
00181             if( !opClass.IsNop() ){
00182                 Scheduler* sched = steerer->Steer( op );
00183                 op->SetScheduler( sched );
00184                 
00185                 ExecUnitIF* execUnit = op->GetExecUnit();
00186                 execUnit->Begin();
00187                 execUnit->Reserve( op, 0 );
00188             
00189                 // emulation
00190                 op->ExecutionBegin();
00191                 op->SetStatus( OpStatus::OS_EXECUTING );
00192                 op->ExecutionEnd();
00193             }
00194 
00195             // [h
00196             if( opClass.IsLoad() ){
00197                 CacheAccess readAccess( op->GetMemAccess(), op, CacheAccess::OT_READ );
00198                 if( m_enableCache ){
00199                     if( m_enableHMPred ){
00200                         hmPred->Predict( op );
00201                     }
00202                     CacheAccessResult result = cache->Read( readAccess, NULL );
00203                     op->SetCacheAccessResult( result );
00204 
00205                     if( m_enableHMPred ){
00206                         bool hit = result.state == CacheAccessResult::ST_HIT;
00207                         hmPred->Finished( op, hit );
00208                         hmPred->Commit( op, hit );
00209                     }
00210                 }
00211 
00212                 if( readAccess.result != MemAccess::MAR_SUCCESS ){
00213                     RUNTIME_WARNING( 
00214                         "An access violation occurs.\n%s\n%s",
00215                         readAccess.ToString().c_str(), op->ToString().c_str() 
00216                     );
00217                 }
00218             }
00219 
00220             // XgA
00221             if( opClass.IsStore() ) {
00222                 CacheAccess writeAccess( op->GetMemAccess(), op, CacheAccess::OT_WRITE );
00223                 memImage->Write( &writeAccess );
00224 
00225                 if( writeAccess.result != MemAccess::MAR_SUCCESS ){
00226                     RUNTIME_WARNING( 
00227                         "An access violation occurs.\n%s\n%s",
00228                         writeAccess.ToString().c_str(), op->ToString().c_str() 
00229                     );
00230                 }
00231 
00232                 if( m_enableCache ){
00233                     CacheAccessResult result = cache->Write( writeAccess, NULL );
00234                     op->SetCacheAccessResult( result );
00235                 }
00236             }
00237             
00238             // 
00239             if( m_enableBPred && opClass.IsBranch() ) {
00240                 bPred->Finished(op);
00241                 bPred->Commit(op);
00242             }
00243 
00244             op->SetStatus( OpStatus::OS_WRITTEN_BACK );
00245 
00246             // dump
00247             g_dumper.Dump( DS_FETCH, op );
00248             g_dumper.Dump( DS_RETIRE, op );
00249 
00250             // ^CA
00251             if( opClass.IsLoad() ) {
00252                 memOrderManager->Commit( op );
00253                 memOrderManager->Retire( op ); // flush: true
00254             }
00255 
00256             cacheSystem->Commit( op );
00257 
00258             // Commit
00259             emulator->Commit( &*op, opInfo );
00260 
00261             // WX^
00262             regDepPred->Commit(op);
00263 
00264             ++opCount;
00265 
00266             // PCAbvf[g
00267             if ( infoIndex == infoCount - 1 ) {
00268                 if (op->GetTaken()) {
00269                     curThreadPC = op->GetTakenPC();
00270                 }else {
00271                     curThreadPC.address += SimISAInfo::INSTRUCTION_WORD_BYTE_SIZE;
00272                 }
00273             }
00274 
00275             inorderList->Commit( op );
00276             inorderList->Retire( op );
00277             inorderList->DestroyOp( op );
00278         }
00279     }
00280 
00281     context->executedInsns  = insnCount;
00282     context->executedCycles = 0;
00283 
00284     // RunsZbg
00285     ISAInfoIF* isaInfo = context->emulator->GetISAInfo();
00286     int logicalRegCount = isaInfo->GetRegisterCount();
00287 
00288     for( int pid = 0; pid < processCount; pid++ ){
00289 
00290         RegDepPredIF* regDepPred = context->threads[pid]->GetRegDepPred();
00291         RegisterFile* regFile    = context->threads[pid]->GetCore()->GetRegisterFile();
00292 
00293         // register value
00294         for(int i = 0; i < logicalRegCount; ++i) {
00295             int phyRegNo = regDepPred->PeekReg( i );
00296             PhyReg* reg  = regFile->GetPhyReg( phyRegNo );
00297             archStateList[pid].registerValue[i] = reg->GetVal();
00298         }
00299     }
00300 
00301 }

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