src/Sim/Dumper/VisualizationDumper.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/Dumper/VisualizationDumper.h"
00035 
00036 #include "Sim/Dumper/DumpState.h"
00037 #include "Sim/Op/Op.h"
00038 #include "Sim/Core/Core.h"
00039 #include "Sim/Dumper/DumpFileName.h"
00040 #include "Version.h"
00041 
00042 using namespace Onikiri;
00043 using namespace std;
00044 using namespace boost;
00045 
00046 static const char g_kanataFileFormatHeader[] = "Kanata";
00047 
00048 VisualizationDumper::OpState::OpState() :
00049     dumpState( DS_INVALID ),
00050     visSerialID( INVALID_VIS_SERIAL ),
00051     inPipeline( false ),
00052     stalled( false ),
00053     lastRawStages()
00054 {
00055 }
00056 
00057 static const String MakeKanataHeaderString()
00058 {
00059     String headerStr;
00060     headerStr.format(
00061         "%s\t%04x\n", 
00062         g_kanataFileFormatHeader,
00063         ONIKIRI_KANATA_FILE_VERSION
00064     );
00065     return headerStr;
00066 }
00067 
00068 VisualizationDumper::VisualizationDumper()
00069 {
00070     m_visLastPrintCycle = 0;
00071     m_visCurrentCycle = 0;
00072     m_enabled = false;
00073     m_skipInsns = 0;
00074     m_visSerialID = 0;
00075 }
00076 
00077 VisualizationDumper::~VisualizationDumper()
00078 {
00079 }
00080 
00081 //
00082 // m_coreStateTable ANZT
00083 //
00084 
00085 VisualizationDumper::OpState* VisualizationDumper::GetOpState( OpIterator op )
00086 {
00087     return &m_coreStateTable[op->GetCore()].opState[op];
00088 }
00089 
00090 DUMP_STATE VisualizationDumper::GetLastState( OpIterator op )
00091 {
00092     return GetOpState(op)->dumpState;
00093 }
00094 
00095 void VisualizationDumper::SetLastState( OpIterator op, DUMP_STATE state )
00096 {
00097     GetOpState(op)->dumpState = state;
00098 }
00099 
00100 u64 VisualizationDumper::GetVisSerialID( OpIterator op )
00101 {
00102     return GetOpState(op)->visSerialID;
00103 }
00104 
00105 void VisualizationDumper::SetVisSerialID( OpIterator op, u64 visSerialID)
00106 {
00107     GetOpState(op)->visSerialID = visSerialID;
00108 }
00109 
00110 
00111 bool VisualizationDumper::IsEnabled()
00112 {
00113     return m_enabled;
00114 }
00115 
00116 // _vXLbv
00117 bool VisualizationDumper::IsDumpSkipped( OpIterator op )
00118 {
00119     return ( GetTotalRetiredInsnCount() < m_skipInsns ) ? true : false;
00120 }
00121 
00122 // DUMP_STATE <> \ヲ
00123 const char* VisualizationDumper::ToStringFromDumpState( DUMP_STATE state )
00124 {
00125     return g_visualizerDumperStrTbl[state];
00126 }
00127 
00128 //
00129 // Additional label information is printed by 'L' command.
00130 //
00131 // CiAhXOpR[hCWX^jD
00132 // Kanata \ヲD
00133 //
00134 void VisualizationDumper::PrintOpInitLabel( const OpIterator op )
00135 {
00136     stringstream label;
00137     label <<
00138         hex << op->GetPC().address <<
00139         dec << " ";
00140 
00141     OpInfo* opInfo = op->GetOpInfo();
00142 
00143     // dst operand\ヲ
00144     int dstNum = op->GetOpInfo()->GetDstNum();
00145     if( dstNum != 0 ){
00146         if( dstNum == 1 ){
00147             label << "r" << opInfo->GetDstOperand( 0 );
00148         }
00149         else{
00150             label << "(";
00151 
00152             bool first = true;
00153             for( int i = 0; i < opInfo->GetDstNum(); i++ ){
00154                 if( !first ){
00155                     label << ", ";
00156                 }
00157                 label << "r" << opInfo->GetDstOperand( i );
00158                 first = false;
00159             }
00160             label << ")";
00161         }
00162 
00163         label << " = ";
00164     }
00165 
00166     // op class\ヲ
00167     //label << OpClassCode::ToString(op->GetOpClass().GetCode()) << "(";
00168     // j[jbN\ヲ
00169     label << opInfo->GetMnemonic() << "(";
00170 
00171     // src operand\ヲ
00172     bool first = true;
00173     for (int j = 0; j < opInfo->GetSrcNum(); j++)
00174     {
00175         if (!first) label << ", ";
00176         label << "r" << opInfo->GetSrcOperand(j);
00177         first = false;
00178     }
00179     label << ")";
00180 
00181     PrintOpLabel( op, POLT_LABEL, label.str() );
00182 }
00183 
00184 //
00185 // Fetchop\ヲ
00186 //
00187 // oF
00188 // >> I 0 0 0
00189 // OoOKv 
00190 // 2 : t@CID 
00191 // 3 : ID 
00192 // 4 : TIDiXbhッqj 
00193 //
00194 void VisualizationDumper::PrintOpInit(OpIterator op)
00195 {
00196     // Update visSerialID.
00197     u64 visSerialID = m_visSerialID;
00198     m_visSerialID++;
00199     SetVisSerialID( op, visSerialID );
00200 
00201     // Print 'I' command.
00202     m_visStream <<
00203         "I\t" << 
00204         visSerialID             << "\t" <<
00205         op->GetGlobalSerialID() << "\t" <<
00206         op->GetTID() << "\n";
00207     
00208     // Additional label information is printed by 'L' command in PrintOpInitLabel.
00209     PrintOpInitLabel( op );
00210 
00211     // Update an op extra state.
00212     OpState* opState = GetOpState( op );
00213     opState->inPipeline = true;
00214     opState->stalled    = false;
00215     opState->lastRawStages.clear();
00216 }
00217 
00218 
00219 
00220 // Print a label text 
00221 void VisualizationDumper::PrintOpLabel(  const OpIterator op, OpLabelType type, const string& label )
00222 {
00223     m_visStream <<
00224         "L\t" << 
00225         GetVisSerialID( op )    << "\t" <<
00226         (type == POLT_LABEL ? '0' : '1' ) << "\t" <<
00227         label << "\n";
00228 }
00229 
00230 void VisualizationDumper::PrintCycle()
00231 {
00232     stringstream stream;
00233     if (m_enabled && m_visLastPrintCycle != m_visCurrentCycle) {
00234         if (m_visLastPrintCycle == 0) {
00235             stream << "C=\t" << m_visCurrentCycle << "\n";
00236         } else {
00237             stream << "C\t" << (m_visCurrentCycle - m_visLastPrintCycle) << "\n";
00238         }
00239         m_visLastPrintCycle = m_visCurrentCycle;
00240     }
00241     m_visStream << stream.str();
00242 }
00243 
00244 
00245 // opVPipelineStage\ヲ
00246 void VisualizationDumper::PrintNextPipelineStage( const OpIterator op, DUMP_STATE state )
00247 {
00248     m_visStream <<
00249         "S\t" << 
00250         GetVisSerialID( op ) << "\t" << 
00251         "0" /*lane*/         << "\t" << 
00252         ToStringFromDumpState(state)         << "\n";
00253 }
00254 
00255 // opOPipelineStageo\ヲ
00256 void VisualizationDumper::PrintLastPipelineStage( const OpIterator op, DUMP_STATE lastState )
00257 {
00258     m_visStream <<
00259         "E\t" << 
00260         GetVisSerialID( op ) << "\t" << 
00261         "0" /*lane*/         << "\t" << 
00262         ToStringFromDumpState(lastState)     << "\n";
00263 }
00264 
00265 void VisualizationDumper::PrintStallBody( OpIterator op, bool stall )
00266 {
00267     const char* tag = stall ? "S\t" : "E\t";
00268     m_visStream <<
00269         tag << 
00270         GetVisSerialID( op ) << "\t" <<
00271         "1\t"/*lane*/ << 
00272         "stl\t" <<
00273         "\n";
00274 }
00275 
00276 // Raw output 
00277 void VisualizationDumper::PrintRawOutput( 
00278     OpIterator op, bool begin, const char*stage, DumpLane lane 
00279 ){
00280     if(!m_enabled)
00281         return;
00282     if( IsDumpSkipped( op ) )
00283         return;
00284 
00285     OpState* opState = GetOpState( op );
00286     if( !opState->inPipeline )
00287         return;
00288 
00289     OpState::Stage* info = &opState->lastRawStages[lane];
00290 
00291     if( begin && info->in ){
00292         PrintRawOutput( op, false, info->name.c_str(), lane );
00293     }
00294 
00295     PrintCycle();
00296 
00297     const char* tag = begin ? "S\t" : "E\t";
00298     m_visStream <<
00299         tag << 
00300         GetVisSerialID( op ) << "\t" <<
00301         lane  << "\t" << 
00302         stage << "\t" <<
00303         "\n";
00304 
00305     info->in   = begin;
00306     info->name = stage;
00307 }
00308 
00309 void VisualizationDumper::PrintStall( const OpIterator op, bool stall )
00310 {
00311     if(!m_enabled)
00312         return;
00313     if( IsDumpSkipped( op ) )
00314         return;
00315     if( !GetOpState( op )->inPipeline )
00316         return;
00317 
00318     OpState* state = GetOpState( op );
00319     ASSERT( 
00320         state->stalled != stall, 
00321         "%s\nOp serial ID: %lld",
00322         stall ?
00323             "Stall overlap." : 
00324             "The op that is not stalled is finished from stall.",
00325         op->GetSerialID() 
00326     );
00327     state->stalled = stall;
00328 
00329     PrintCycle();
00330     PrintStallBody( op, stall );
00331 }
00332 
00333 void VisualizationDumper::PrintStallBegin( const OpIterator op )
00334 {
00335     PrintStall( op, true );
00336 }
00337 
00338 void VisualizationDumper::PrintStallEnd( const OpIterator op )
00339 {
00340     PrintStall( op, false );
00341 }
00342 
00343 // opRetire/Flush\ヲ
00344 void VisualizationDumper::PrintOpEndLabel( const OpIterator op )
00345 {
00346     OpInfo* opInfo = op->GetOpInfo();
00347     OpStatus opState = op->GetStatus();
00348     stringstream label;
00349 
00350     // WX^
00351     if( opState >= OpStatus::OS_RENAME ){
00352         
00353         // dst operand\ヲ
00354         int dstNum = opInfo->GetDstNum();
00355         if( dstNum != 0 ){
00356             if( dstNum == 1 ){
00357                 label << "p" << op->GetDstReg(0) <<
00358                     ":0x" << hex << op->GetDst(0) << dec;
00359             } 
00360             else{
00361                 bool first = true;
00362                 label << "(";
00363                 for (int i = 0; i < opInfo->GetDstNum(); i++){
00364                     if( !first ){
00365                         label << ", ";
00366                     }
00367                     label << "p" << op->GetDstReg(i) <<
00368                         ":0x" << hex << op->GetDst(i) << dec;
00369                     first = false;
00370                 }
00371                 label << ")\n";
00372             }
00373             label << " = ";
00374         }
00375 
00376     }
00377 
00378     // op class\ヲ
00379     label << OpClassCode::ToString(op->GetOpClass().GetCode()) << "( ";
00380     // j[jbN\ヲ
00381     //label << opInfo->GetMnemonic() << "( ";
00382 
00383     // src operand\ヲ
00384     if( opState >= OpStatus::OS_RENAME ){
00385         bool first = true;
00386         for( int j = 0; j < opInfo->GetSrcNum(); j++ ){
00387             if( !first ){
00388                 label << ", ";
00389             }
00390             label <<
00391                 "p" << op->GetSrcReg(j) <<
00392                 ":0x" << hex << op->GetSrc(j) << dec;
00393             first = false;
00394         }
00395     }
00396 
00397     label << " )";
00398 
00399     // Dump a memory address.
00400     if( op->GetOpClass().IsMem() ){
00401         label <<
00402             " [addr: 0x" << 
00403             hex << op->GetMemAccess().address.address << dec << "]";
00404     }
00405 
00406 
00407     // o
00408     PrintOpLabel( op, POLT_DETAIL, label.str() );
00409 
00410 }
00411 
00412 void VisualizationDumper::PrintOpEnd( const OpIterator op, DUMP_STATE state )
00413 {
00414     // Close all unclosed raw stages.
00415     OpState* opExState = GetOpState( op );
00416 
00417     typedef map< DumpLane, OpState::Stage >::iterator iterator;
00418     for( iterator i = opExState->lastRawStages.begin(); 
00419         i != opExState->lastRawStages.end();
00420         ++i
00421     ){
00422         if( i->second.in ){
00423             PrintRawOutput( op, false, i->second.name.c_str(), i->first );
00424         }
00425     }
00426 
00427     PrintOpEndLabel( op );
00428 
00429     // {
00430     m_visStream << 
00431         "R\t" << 
00432         GetVisSerialID( op ) << "\t" <<                 // serial ID
00433         op->GetRetireID() << "\t" <<                    // Retire ID
00434         (state == DS_RETIRE ? "0" : "1") << "\n";       // Retire:0 Flush:1
00435     
00436     // Update an op state.
00437     GetOpState( op )->inPipeline = false;
00438 }
00439 
00440 // open FileStream
00441 void VisualizationDumper::Initialize( 
00442     const String& suffix, 
00443     PhysicalResourceArray<Core>& coreList 
00444 ){
00445     m_visCurrentCycle = 0;
00446     m_visLastPrintCycle = 0;
00447 
00448     LoadParam();
00449     if( IsEnabled() ){
00450         String fileName = 
00451             g_env.GetHostWorkPath() + 
00452             MakeDumpFileName( m_visFileName, suffix, m_gzipEnabled );
00453 
00454         if (m_gzipEnabled){
00455             m_visStream.push( 
00456                 iostreams::gzip_compressor( 
00457                     iostreams::gzip_params(m_gzipLevel) 
00458                 )
00459             );
00460         }
00461 
00462         m_visStream.push( iostreams::file_sink( fileName, ios::binary ) );
00463         m_visStream << MakeKanataHeaderString().c_str();
00464 
00465 
00466         for( int i = 0; i < coreList.GetSize(); i++ ){
00467             CoreState* coreState = &m_coreStateTable[ coreList[i] ];
00468             coreState->opState.Resize( *coreList[i]->GetOpArray() );
00469             for( int j = 0; j < coreList[i]->GetThreadCount(); j++ ){
00470                 m_threadStateTable[ coreList[i]->GetThread(j) ].retiredInsnCount = 0;
00471             }
00472             
00473         }
00474     }
00475 }
00476 
00477 // close FileStream
00478 void VisualizationDumper::Finalize()
00479 {
00480     ReleaseParam();
00481 }
00482 
00483 // opState(PipelineStage/Retire/Flush)\ヲ
00484 // StateZk`\ヲ(shrink(State))
00485 // shrink()o^State3\ヲ
00486 void VisualizationDumper::PrintOpState(OpIterator op, DUMP_STATE state)
00487 {
00488     if( !m_enabled )
00489         return;
00490     
00491     if( IsDumpSkipped( op ) )
00492         return;
00493 
00494     if( !GetOpState( op )->inPipeline && state != DS_FETCH )
00495         return;
00496 
00497     PrintCycle();
00498 
00499     // opvisDump(Fetch)Aop\ヲ
00500     if(state == DS_FETCH ){
00501         PrintOpInit(op);
00502     }
00503     else{
00504         // OstageAstageI\ヲ: FetchO
00505         PrintLastPipelineStage( op, GetLastState(op) );
00506     }
00507 
00508     if( state == DS_RETIRE || state == DS_FLUSH ){
00509         // PipelineStageSI\ヲFopRetire/Flush
00510         PrintOpEnd( op, state );
00511     } else {
00512         // opVPipelineStage\ヲ
00513         PrintNextPipelineStage( op, state );
00514         SetLastState( op, state ); // stageXV
00515     }
00516 }
00517 
00518 
00519 // opopWakeUp(OpWakeUpEvent)AopDependency\ヲ
00520 void VisualizationDumper::PrintOpDependency(
00521     const OpIterator producerOp, 
00522     const OpIterator consumerOp, 
00523     DumpDependency type 
00524 ){
00525     if( !m_enabled )
00526         return;
00527     if( IsDumpSkipped( producerOp ) )
00528         return;
00529 
00530     if( !GetOpState( consumerOp )->inPipeline || !GetOpState( producerOp )->inPipeline )
00531         return;
00532 
00533     PrintCycle();
00534     m_visStream << 
00535         "W\t" <<
00536         GetVisSerialID( consumerOp ) << "\t" << 
00537         GetVisSerialID( producerOp ) << "\t" << 
00538         type << "\n";
00539 }
00540 
00541 // VisualizationDumpercycle
00542 void VisualizationDumper::SetCurrentCycle(const s64 cycle)
00543 {
00544     m_visCurrentCycle = cycle;
00545 }
00546 
00547 void VisualizationDumper::SetCurrentInsnCount( Thread* thread, const s64 count )
00548 {
00549     m_threadStateTable[thread].retiredInsnCount = count;
00550 }
00551 
00552 s64 VisualizationDumper::GetTotalRetiredInsnCount()
00553 {
00554     s64 count = 0;
00555     for( ThreadStateMap::iterator i = m_threadStateTable.begin(); i != m_threadStateTable.end(); ++i ){
00556         count += i->second.retiredInsnCount;
00557     }
00558     return count;
00559 }

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