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/Pipeline/Fetcher/Steerer/IcountFetchThreadSteerer.h"
00035
00036 #include "Sim/Thread/Thread.h"
00037 #include "Sim/Op/Op.h"
00038 #include "Sim/Pipeline/Scheduler/Scheduler.h"
00039 #include "Sim/InorderList/InorderList.h"
00040
00041 using namespace Onikiri;
00042
00043 IcountFetchThreadSteerer::IcountFetchThreadSteerer() :
00044 m_nextThread(0),
00045 m_evaluatedThread(0)
00046 {
00047 }
00048
00049 IcountFetchThreadSteerer::~IcountFetchThreadSteerer()
00050 {
00051 }
00052
00053 void IcountFetchThreadSteerer::Initialize(InitPhase phase)
00054 {
00055 if (phase == INIT_PRE_CONNECTION){
00056 LoadParam();
00057 return;
00058 }
00059 if (phase == INIT_POST_CONNECTION){
00060
00061 CheckNodeInitialized( "thread", m_thread );
00062
00063 }
00064 }
00065
00066 void IcountFetchThreadSteerer::Finalize()
00067 {
00068 ReleaseParam();
00069 }
00070
00071 Thread* IcountFetchThreadSteerer::SteerThread(bool update)
00072 {
00073 int threadCount = m_thread.GetSize();
00074 std::vector<int> frontendInsnNum(threadCount,0);
00075
00076
00077 for (int tid = 0; tid < threadCount; tid++)
00078 {
00079 InorderList* inorderList = m_thread[tid]->GetInorderList();
00080 for (OpIterator op = inorderList->GetFrontOp(); op != OpIterator(0); op = inorderList->GetNextIndexOp(op))
00081 {
00082 if ( !op->IsDispatched() ||
00083 (!op->GetOpClass().IsNop() && op->GetScheduler()->IsInScheduler(op)) )
00084 {
00085 frontendInsnNum[tid]++;
00086 }
00087 }
00088 }
00089
00090
00091 int currentFetchThread = m_nextThread;
00092 int count = 0;
00093 bool found = true;
00094 while ( !m_thread[currentFetchThread]->IsActive() )
00095 {
00096 currentFetchThread = (currentFetchThread + 1) % threadCount;
00097 count++;
00098 if( count > threadCount ){
00099 found = false;
00100 break;
00101 }
00102 }
00103
00104 if( !found ){
00105 if( update )
00106 m_nextThread = currentFetchThread;
00107 return NULL;
00108 }
00109
00110
00111 int targetThread = currentFetchThread;
00112 count = 0;
00113 do
00114 {
00115 currentFetchThread = (currentFetchThread + 1) % threadCount;
00116 if (m_thread[currentFetchThread]->IsActive() && frontendInsnNum[targetThread] > frontendInsnNum[currentFetchThread])
00117 {
00118 targetThread = currentFetchThread;
00119 }
00120 count++;
00121 } while ( count <= threadCount );
00122
00123 if( update ){
00124 if ( m_evaluatedThread != targetThread )
00125 {
00126 targetThread = m_evaluatedThread;
00127 m_nextThread = (targetThread + 1) % threadCount;
00128 }
00129 else
00130 {
00131 m_nextThread = (targetThread + 1) % threadCount;
00132 }
00133 }
00134 else
00135 {
00136 m_evaluatedThread = targetThread;
00137 }
00138
00139 return m_thread[targetThread];
00140 }