src/Sim/Pipeline/Dispatcher/Dispatcher.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/Pipeline/Dispatcher/Dispatcher.h"
00035 
00036 #include "Sim/Dumper/Dumper.h"
00037 #include "Sim/Foundation/Hook/HookUtil.h"
00038 #include "Sim/Op/Op.h"
00039 #include "Sim/Pipeline/Scheduler/Scheduler.h"
00040 #include "Sim/Core/Core.h"
00041 
00042 using namespace std;
00043 using namespace boost;
00044 using namespace Onikiri;
00045 
00046 namespace Onikiri 
00047 {
00048     HookPoint<Dispatcher, Dispatcher::DispatchHookParam> Dispatcher::s_dispatchEvaluateHook;
00049     HookPoint<Dispatcher, Dispatcher::DispatchHookParam> Dispatcher::s_dispatchUpdateHook;
00050 };  // namespace Onikiri
00051 
00052 Dispatcher::SchedulerInfo::SchedulerInfo() :
00053     index(0),
00054     saturateCount(0),
00055     scheduler(0),
00056     numDispatchedOps(0)
00057 {
00058 }
00059 
00060 
00061 Dispatcher::Dispatcher() :
00062     m_dispatchLatency(0)
00063 {
00064 }
00065 
00066 Dispatcher::~Dispatcher()
00067 {
00068 }
00069 
00070 void Dispatcher::Initialize( InitPhase phase )
00071 {
00072     PipelineNodeBase::Initialize( phase );
00073 
00074     if( phase == INIT_PRE_CONNECTION ){
00075         LoadParam();
00076     }
00077     else if( phase == INIT_POST_CONNECTION ){
00078 
00079         // INIT_POST_CONNECTION
00080         m_numScheduler = GetCore()->GetNumScheduler();
00081         if( MAX_SCHEDULER_NUM < m_numScheduler ){
00082             THROW_RUNTIME_ERROR( 
00083                 "The number of schedulers is greater than MAX_SCHEDULER_NUM." 
00084             );
00085         }
00086 
00087         ASSERT( m_schedInfo.size() == 0 );
00088         m_schedInfo.resize( m_numScheduler );
00089 
00090         for( int i = 0; i < m_numScheduler; ++i ){
00091             Scheduler* sched = GetCore()->GetScheduler(i);
00092             int index = sched->GetIndex();
00093             ASSERT( i == index, "Mismatched scheduler's indeces." );
00094 
00095             m_schedInfo[i].index = index;
00096             m_schedInfo[i].scheduler = sched;
00097             m_schedInfo[i].dispatchingOps.resize( *GetCore()->GetOpArray() );
00098         }
00099     
00100         // VCX^XiresizejSchedulerSaturateCount
00101         // ParamDBo^x
00102         LoadParam();
00103 
00104         // member `FbN
00105         if ( m_dispatchLatency == 0 ) {
00106             THROW_RUNTIME_ERROR( "A dispatch latency must be more than 0." );
00107         }
00108     }
00109 }
00110 
00111 void Dispatcher::Finalize()
00112 {
00113     m_stallCylcles.clear();
00114     for( vector< SchedulerInfo >::iterator i = m_schedInfo.begin(); i != m_schedInfo.end(); ++i ){
00115         m_stallCylcles.push_back( i->saturateCount );
00116         m_schedulerName.push_back( i->scheduler->GetName() );
00117         m_numDispatchedOps.push_back( i->numDispatchedOps );
00118     }
00119 
00120     ReleaseParam();
00121 }
00122 
00123 Dispatcher::SchedulerInfo* Dispatcher::GetSchedulerInfo( OpIterator op )
00124 {
00125     Scheduler* sched = op->GetScheduler();
00126     int index = sched->GetIndex();
00127     return &m_schedInfo[index];
00128 }
00129 
00130 void Dispatcher::Evaluate()
00131 {
00132     BaseType::Evaluate();
00133 
00134 
00135     // Count the number of all dispatching ops.
00136     DispatchingOpNums dispatchingOps;
00137     for( int i = 0; i < m_numScheduler; i++ ){
00138         dispatchingOps.push_back( (int)m_schedInfo[i].dispatchingOps.size() );
00139     }
00140 
00141     DispatchHookParam hookParam;
00142     hookParam.dispatchingOps = &dispatchingOps;
00143     for( PipelineLatch::iterator i = m_latch.begin(); i != m_latch.end(); ++i ){
00144         // Count the number of dispatching ops.
00145         hookParam.dispatch = true;
00146         HOOK_SECTION_OP_PARAM( s_dispatchEvaluateHook, *i, hookParam ){
00147             if( hookParam.dispatch ){
00148                 dispatchingOps[ (*i)->GetScheduler()->GetIndex() ]++;
00149             }
00150         }
00151     }
00152 
00153     // Can allocate enough entries in schedulers?
00154     bool stall = false;
00155     for( int i = 0; i < m_numScheduler; i++ ){
00156         if( !m_schedInfo[i].scheduler->CanAllocate( dispatchingOps[i] ) ){
00157             stall = true;
00158             m_schedInfo[i].saturateCount++;
00159         }
00160     }
00161 
00162     if( stall ){
00163         // Stall this node and upper pipelines.
00164         // Do not stall ops where dispatching is already 
00165         // started before this cycle.
00166         StallThisNodeAndUpperThisCycle();
00167     }
00168 }
00169 
00170 void Dispatcher::Dispatch( OpIterator op )
00171 {   
00172     SchedulerInfo* schd = GetSchedulerInfo(op);
00173     op->SetStatus( OpStatus::OS_DISPATCHING );
00174     schd->dispatchingOps.push_back( op );
00175     //schd->pipeline->EnterPipeline( 
00176     GetLowerPipeline()->EnterPipeline(
00177         op, m_dispatchLatency - 1, op->GetScheduler() 
00178     );  
00179     schd->numDispatchedOps++;   
00180     g_dumper.Dump( DS_DISPATCH, op );
00181 }
00182 
00183 // Dispatch all ops in the latch if a dispatcher is not stalled.
00184 void Dispatcher::Update()
00185 {
00186     // Count the number of all dispatching ops.
00187     DispatchingOpNums dispatchingOps;
00188     for( int i = 0; i < m_numScheduler; i++ ){
00189         dispatchingOps.push_back( (int)m_schedInfo[i].dispatchingOps.size() );
00190     }
00191     DispatchHookParam hookParam;
00192     hookParam.dispatchingOps = &dispatchingOps;
00193 
00194     for( PipelineLatch::iterator i = m_latch.begin(); 
00195          i != m_latch.end(); 
00196          /*nothing*/ 
00197     ){
00198         OpIterator op = *i;
00199         hookParam.dispatch = true;
00200         HOOK_SECTION_OP_PARAM( s_dispatchUpdateHook, op, hookParam ){
00201             if( hookParam.dispatch ){
00202                 Dispatch( op );
00203             }
00204         }
00205         i = m_latch.erase( i );
00206     }
00207 }
00208 
00209 
00210 void Dispatcher::ExitLowerPipeline( OpIterator op )
00211 {
00212     SchedulerInfo* schd = GetSchedulerInfo( op );
00213     schd->dispatchingOps.find_and_erase( op );
00214 }
00215 
00216 void Dispatcher::Retire( OpIterator op )
00217 {
00218     PipelineNodeBase::Retire( op );
00219     Delete( op, false );
00220 }
00221 
00222 void Dispatcher::Flush( OpIterator op )
00223 {
00224     PipelineNodeBase::Flush( op );
00225     Delete( op, true );
00226 }
00227 
00228 void Dispatcher::Delete( OpIterator op, bool flush )
00229 {
00230 
00231     if( op->GetStatus() < OpStatus::OS_DISPATCHING ||
00232         op->GetStatus() > OpStatus::OS_DISPATCHED
00233     ){
00234         return;
00235     }
00236 
00237     SchedulerInfo* schd = GetSchedulerInfo( op );
00238     schd->dispatchingOps.find_and_erase( op );
00239 }

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