source-engine/engine/dt_instrumentation.cpp

240 lines
4.7 KiB
C++
Raw Normal View History

2020-04-23 00:56:21 +08:00
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#if (defined(_WIN32) && (!defined(_X360) ) )
#include <windows.h>
#endif
#include "tier0/platform.h"
#include "tier0/icommandline.h"
#include "dt_instrumentation.h"
#include "utlvector.h"
#include "utllinkedlist.h"
#include "tier0/fasttimer.h"
#include "utllinkedlist.h"
#include "tier0/dbg.h"
#include "tier1/utlstring.h"
#include "dt_recv_decoder.h"
#include "filesystem.h"
#include "filesystem_engine.h"
#include "cdll_int.h"
#include "client.h"
#include "common.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
bool g_bDTIEnabled = false;
const char *g_pDTIFilename;
class CDTIProp
{
public:
CDTIProp()
{
m_nDecodes = m_nDataBits = m_nIndexBits = 0;
}
CUtlString m_Name;
int m_nDecodes;
int m_nDataBits;
int m_nIndexBits;
};
class CDTIRecvTable
{
public:
CDTIRecvTable()
{
m_bSawAction = false;
}
CUtlString m_Name;
CUtlVector<CDTIProp> m_Props;
bool m_bSawAction;
};
CUtlLinkedList<CDTIRecvTable*, int> g_DTIRecvTables;
void DTI_Init()
{
#if ( defined( IS_WINDOWS_PC ) && (! defined( SWDS ) ) )
extern IVEngineClient *engineClient;
if ( CommandLine()->FindParm( "-dti" ) && !g_bDTIEnabled )
{
g_bDTIEnabled = true;
SYSTEMTIME systemTime;
GetLocalTime( &systemTime );
char dtiFileName[MAX_PATH];
char dtiLevelName[MAX_PATH];
V_FileBase( engineClient->GetLevelName(), dtiLevelName, ARRAYSIZE( dtiLevelName ) );
V_snprintf( dtiFileName, ARRAYSIZE( dtiFileName ), "dti_client_%s_%02d%02d%02d-%02d%02d%02d.csv",
dtiLevelName,
systemTime.wYear % 100, systemTime.wMonth, systemTime.wDay,
systemTime.wHour, systemTime.wMinute, systemTime.wSecond );
g_pDTIFilename = COM_StringCopy( dtiFileName );
}
#endif
}
void DTI_Term()
{
if ( g_bDTIEnabled )
{
DTI_Flush();
g_DTIRecvTables.PurgeAndDeleteElements();
delete g_pDTIFilename;
g_pDTIFilename = NULL;
g_bDTIEnabled = false;
}
}
void DTI_Flush()
{
if ( !g_bDTIEnabled )
return;
FileHandle_t fp = g_pFileSystem->Open( g_pDTIFilename, "wt" );
if( fp != FILESYSTEM_INVALID_HANDLE )
{
// Write the header.
g_pFileSystem->FPrintf( fp,
"Class"
",Prop"
",Decode Count"
",Total Bits"
",Avg Bits"
",Total Index Bits"
",Avg Index Bits"
",=SUM(D:D)"
"\n" );
int row = 2;
FOR_EACH_LL( g_DTIRecvTables, iTable )
{
CDTIRecvTable *pTable = g_DTIRecvTables[iTable];
if ( !pTable->m_bSawAction )
continue;
for ( int iProp=0; iProp < pTable->m_Props.Count(); iProp++ )
{
CDTIProp *pProp = &pTable->m_Props[iProp];
if ( pProp->m_nDecodes == 0 )
continue;
g_pFileSystem->FPrintf( fp,
// Class/Prop names
"%s"
",%s"
// Decode count
",%d"
// Total/Avg bits
",%d"
",%.3f"
// Total/Avg index bits
",%d"
",%.3f"
",=D%d/H$1"
"\n",
// Class/Prop names
pTable->m_Name.String(),
pProp->m_Name.String(),
// Decode count
pProp->m_nDecodes,
// Total/Avg bits
pProp->m_nDataBits,
(float)pProp->m_nDataBits / pProp->m_nDecodes,
// Total/Avg index bits
pProp->m_nIndexBits,
(float)pProp->m_nIndexBits / pProp->m_nDecodes,
row++
);
}
}
g_pFileSystem->Close( fp );
Msg( "DTI: wrote client stats into %s.\n", g_pDTIFilename );
}
}
void DTI_HookRecvDecoder( CRecvDecoder *pDecoder )
{
if ( !g_bDTIEnabled )
return;
bool dtiEnabled = CommandLine()->FindParm("-dti" ) > 0;
CDTIRecvTable *pTable = new CDTIRecvTable;
pTable->m_Name.Set( pDecoder->GetName() );
pTable->m_Props.SetSize( pDecoder->GetNumProps() );
for ( int i=0; i < pTable->m_Props.Count(); i++ )
{
const SendProp *pSendProp = pDecoder->GetSendProp( i );
if ( !dtiEnabled )
{
pTable->m_Props[i].m_Name.Set( pSendProp->GetName() );
}
else
{
char *parentArrayPropName = const_cast< char * >(const_cast< SendProp * >(pSendProp)->GetParentArrayPropName());
if ( parentArrayPropName )
{
char temp[256];
V_snprintf( temp, sizeof( temp ), "%s:%s", parentArrayPropName, pSendProp->GetName() );
pTable->m_Props[i].m_Name.Set( temp );
}
else
{
pTable->m_Props[i].m_Name.Set( pSendProp->GetName() );
}
}
}
g_DTIRecvTables.AddToTail( pTable );
pDecoder->m_pDTITable = pTable;
}
void _DTI_HookDeltaBits( CRecvDecoder *pDecoder, int iProp, int nDataBits, int nIndexBits )
{
CDTIRecvTable *pTable = pDecoder->m_pDTITable;
if ( !pTable )
return;
CDTIProp *pProp = &pTable->m_Props[iProp];
pProp->m_nDecodes++;
pProp->m_nDataBits += nDataBits;
pProp->m_nIndexBits += nIndexBits;
pTable->m_bSawAction = true;
}