00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <pch.h>
00033
00034 #include "Sim/System/SimulationSystem/SimulationSystem.h"
00035
00036 #include "Sim/Dumper/Dumper.h"
00037 #include "Sim/Foundation/Hook/HookUtil.h"
00038
00039 #include "Sim/Foundation/TimeWheel/TimeWheel.h"
00040 #include "Sim/Pipeline/Fetcher/Fetcher.h"
00041 #include "Sim/Pipeline/Renamer/Renamer.h"
00042 #include "Sim/Pipeline/Dispatcher/Dispatcher.h"
00043 #include "Sim/Pipeline/Scheduler/Scheduler.h"
00044 #include "Sim/Pipeline/Retirer/Retirer.h"
00045 #include "Sim/InorderList/InorderList.h"
00046
00047
00048 namespace Onikiri
00049 {
00050 HookPoint<SimulationSystem> SimulationSystem::s_systemInitHook;
00051
00052 HookPoint<SimulationSystem> SimulationSystem::s_cycleBeginHook;
00053 HookPoint<SimulationSystem> SimulationSystem::s_cycleEvaluateHook;
00054 HookPoint<SimulationSystem> SimulationSystem::s_cycleTransitionHook;
00055 HookPoint<SimulationSystem> SimulationSystem::s_cycleUpdateHook;
00056 HookPoint<SimulationSystem> SimulationSystem::s_cycleEndHook;
00057 }
00058
00059 using namespace std;
00060 using namespace boost;
00061 using namespace Onikiri;
00062
00063 SimulationSystem::SimulationSystem()
00064 {
00065 m_context = NULL;
00066 }
00067
00068 void SimulationSystem::Run( SystemContext* context )
00069 {
00070 try{
00071 m_context = context;
00072 InitializeResources();
00073
00074 context->executedCycles = 1;
00075 s64 numInsns = context->executionInsns;
00076 s64 numCycles = context->executionCycles;
00077
00078 while(true){
00079 context->globalClock->Tick();
00080
00081 for( int i = 0; i < context->threads.GetSize(); i++ ){
00082 Thread* thread = context->threads[i];
00083 g_dumper.SetCurrentInsnCount( thread, thread->GetCore()->GetRetirer()->GetNumRetiredInsns() );
00084 g_dumper.SetCurrentCycle( thread, context->executedCycles );
00085 }
00086
00087 SimulateCycle();
00088
00089 bool exitSimulation = true;
00090 s64 retiredInsns = 0;
00091 for( int i = 0; i < context->cores.GetSize(); i++ ){
00092 Core* core = context->cores[i];
00093 if( !core->GetRetirer()->IsEndOfProgram() ){
00094
00095 exitSimulation = false;
00096 }
00097 retiredInsns += core->GetRetirer()->GetNumRetiredInsns();
00098 }
00099
00100
00101 if(exitSimulation){
00102 break;
00103 }
00104 else if( numCycles > 0 ){
00105
00106 if( context->executedCycles >= numCycles )
00107 break;
00108 }
00109 else{
00110
00111 if( retiredInsns >= numInsns )
00112 break;
00113 }
00114
00115 ++context->executedCycles;
00116 }
00117
00118
00119 context->executedInsns.clear();
00120 for( int i = 0; i < context->threads.GetSize(); i++ ){
00121 context->executedInsns.push_back( context->threads[i]->GetInorderList()->GetRetiredInsns() );
00122 }
00123 }
00124 catch( std::runtime_error& error ){
00125 String msg;
00126 msg.format(
00127 "%s\n"
00128 "Last simulated cycle: %lld\n" ,
00129 error.what(),
00130 m_context->executedCycles
00131 );
00132
00133 throw std::runtime_error( msg.c_str() );
00134 }
00135 }
00136
00137
00138 void SimulationSystem::InitializeResources()
00139 {
00140 s_systemInitHook.Trigger( this, this, HookType::HOOK_BEFORE );
00141 if( !s_systemInitHook.HasAround() ){
00142 InitializeResourcesBody();
00143 s_systemInitHook.Trigger( this, this, HookType::HOOK_AFTER );
00144 }
00145 else{
00146 s_systemInitHook.Trigger( this, this, HookType::HOOK_AROUND );
00147 }
00148 }
00149
00150
00151 void SimulationSystem::InitializeResourcesBody()
00152 {
00153 PhysicalResourceArray<Core>& core = m_context->cores;
00154 PhysicalResourceArray<Thread>& thread = m_context->threads;
00155 PhysicalResourceArray<Cache>& caches = m_context->caches;
00156
00157 m_coreResources.resize( core.GetSize() );
00158 m_threadResources.resize( thread.GetSize() );
00159 m_memResources.resize( caches.GetSize() );
00160
00161 for( int i = 0; i < thread.GetSize(); i++ ){
00162 ThreadResources& res = m_threadResources[i];
00163 res.memOrderManager = thread[i]->GetMemOrderManager();
00164 }
00165
00166
00167
00168
00169 for( int i = 0; i < caches.GetSize(); i++ ){
00170 m_clockedResources.push_back( caches[i] );
00171 }
00172
00173 for( int i = 0; i < core.GetSize(); i++ ){
00174 CoreResources& res = m_coreResources[i];
00175
00176 res.core = core[i];
00177 m_clockedResources.push_back( core[i]->GetRetirer() );
00178
00179 for( int j = 0; j < core[i]->GetNumScheduler(); j++ ){
00180 Scheduler* scheduler = core[i]->GetScheduler( j );
00181 m_clockedResources.push_back( scheduler );
00182 }
00183
00184 m_clockedResources.push_back( core[i]->GetDispatcher() );
00185 m_clockedResources.push_back( core[i]->GetRenamer() );
00186 m_clockedResources.push_back( core[i]->GetFetcher() );
00187
00188 m_clockedResources.push_back( core[i] );
00189 }
00190
00191 sort(
00192 m_clockedResources.begin(),
00193 m_clockedResources.end(),
00194 ClockedResourceBase::ComparePriority()
00195 );
00196
00197
00198
00199
00200 for( int i = 0; i < caches.GetSize(); i++ ){
00201 m_timeWheels.push_back( caches[i]->GetLowerPipeline() );
00202 }
00203
00204 for( int i = 0; i < core.GetSize(); i++ ){
00205 CoreResources& res = m_coreResources[i];
00206
00207 res.core = core[i];
00208 m_timeWheels.push_back( core[i]->GetRetirer()->GetLowerPipeline() );
00209
00210 for( int j = 0; j < core[i]->GetNumScheduler(); j++ ){
00211 Scheduler* scheduler = core[i]->GetScheduler( j );
00212 m_timeWheels.push_back( scheduler->GetLowerPipeline() );
00213 }
00214
00215 m_timeWheels.push_back( core[i]->GetDispatcher()->GetLowerPipeline() );
00216 m_timeWheels.push_back( core[i]->GetRenamer()->GetLowerPipeline() );
00217 m_timeWheels.push_back( core[i]->GetFetcher()->GetLowerPipeline() );
00218 }
00219
00220
00221 }
00222
00223 SimulationSystem::SystemContext* SimulationSystem::GetContext()
00224 {
00225 return m_context;
00226 }
00227
00228 void SimulationSystem::CycleBegin()
00229 {
00230 ClockedResourceList::iterator end = m_clockedResources.end();
00231 for( ClockedResourceList::iterator i = m_clockedResources.begin(); i != end; ++i ){
00232 (*i)->Begin();
00233 }
00234 }
00235
00236 void SimulationSystem::CycleEvaluate()
00237 {
00238 m_priorityEventList.ExtractEvent( &m_timeWheels );
00239
00240 m_priorityEventList.BeginEvaluate();
00241
00242 ClockedResourceList::iterator end = m_clockedResources.end();
00243 for( ClockedResourceList::iterator i = m_clockedResources.begin(); i != end; ++i ){
00244 ClockedResourceIF* res = *i;
00245 m_priorityEventList.TriggerEvaluate( res->GetPriority() );
00246 res->Evaluate();
00247 }
00248
00249 m_priorityEventList.EndEvaluate();
00250 }
00251
00252 void SimulationSystem::CycleTransition()
00253 {
00254 ClockedResourceList::iterator end = m_clockedResources.end();
00255 for( ClockedResourceList::iterator i = m_clockedResources.begin(); i != end; ++i ){
00256 (*i)->Transition();
00257 }
00258 }
00259
00260 void SimulationSystem::CycleUpdate()
00261 {
00262 m_priorityEventList.BeginUpdate();
00263
00264 ClockedResourceList::iterator end = m_clockedResources.end();
00265 for( ClockedResourceList::iterator i = m_clockedResources.begin(); i != end; ++i ){
00266 ClockedResourceIF* res = *i;
00267 m_priorityEventList.TriggerUpdate( res->GetPriority() );
00268 res->TriggerUpdate();
00269 }
00270
00271 m_priorityEventList.EndUpdate();
00272 }
00273
00274 void SimulationSystem::CycleEnd()
00275 {
00276 ClockedResourceList::iterator end = m_clockedResources.end();
00277 for( ClockedResourceList::iterator i = m_clockedResources.begin(); i != end; ++i ){
00278 (*i)->End();
00279 }
00280 }
00281
00282 void SimulationSystem::SimulateCycle()
00283 {
00284 if( s_cycleBeginHook.IsAnyHookRegistered() ||
00285 s_cycleEvaluateHook.IsAnyHookRegistered() ||
00286 s_cycleTransitionHook.IsAnyHookRegistered() ||
00287 s_cycleUpdateHook.IsAnyHookRegistered() ||
00288 s_cycleEndHook.IsAnyHookRegistered()
00289 ){
00290 HookEntry( this, &SimulationSystem::CycleBegin, &s_cycleBeginHook );
00291 HookEntry( this, &SimulationSystem::CycleEvaluate, &s_cycleEvaluateHook );
00292 HookEntry( this, &SimulationSystem::CycleTransition, &s_cycleTransitionHook );
00293 HookEntry( this, &SimulationSystem::CycleUpdate, &s_cycleUpdateHook );
00294 HookEntry( this, &SimulationSystem::CycleEnd, &s_cycleEndHook );
00295 }
00296 else{
00297 CycleBegin();
00298 CycleEvaluate();
00299 CycleTransition();
00300 CycleUpdate();
00301 CycleEnd();
00302 }
00303
00304 }