mirror of
https://github.com/libretro/Play-.git
synced 2024-11-30 20:21:25 +00:00
Rewrote the profiler to make it simpler to use and more accurate.
git-svn-id: http://svn.purei.org/purei/trunk@1051 b36208d7-6611-0410-8bec-b1987f11c4a2
This commit is contained in:
parent
c56c249ff4
commit
a5aaa0bea0
@ -445,7 +445,7 @@ void CDMAC::SetRegister(uint32 nAddress, uint32 nData)
|
||||
{
|
||||
|
||||
#ifdef PROFILE
|
||||
CProfiler::GetInstance().BeginZone(PROFILE_DMACZONE);
|
||||
CProfilerZone profilerZone(PROFILE_DMACZONE);
|
||||
#endif
|
||||
|
||||
switch(nAddress)
|
||||
@ -839,10 +839,6 @@ void CDMAC::SetRegister(uint32 nAddress, uint32 nData)
|
||||
DisassembleSet(nAddress, nData);
|
||||
#endif
|
||||
|
||||
#ifdef PROFILE
|
||||
CProfiler::GetInstance().EndZone();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void CDMAC::LoadState(CZipArchiveReader& archive)
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include "Profiler.h"
|
||||
#include "Log.h"
|
||||
|
||||
#define LOG_NAME ("gif")
|
||||
#define LOG_NAME ("gif")
|
||||
|
||||
#ifdef PROFILE
|
||||
#define PROFILE_GIFZONE "GIF"
|
||||
@ -208,7 +208,7 @@ uint32 CGIF::ProcessPacket(uint8* pMemory, uint32 nAddress, uint32 nEnd)
|
||||
static CGSHandler::RegisterWriteList writeList;
|
||||
|
||||
#ifdef PROFILE
|
||||
CProfiler::GetInstance().BeginZone(PROFILE_GIFZONE);
|
||||
CProfilerZone profilerZone(PROFILE_GIFZONE);
|
||||
#endif
|
||||
|
||||
#ifdef _DEBUG
|
||||
@ -273,10 +273,6 @@ uint32 CGIF::ProcessPacket(uint8* pMemory, uint32 nAddress, uint32 nEnd)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef PROFILE
|
||||
CProfiler::GetInstance().EndZone();
|
||||
#endif
|
||||
|
||||
if(m_gs != NULL && writeList.size() != 0)
|
||||
{
|
||||
CGSHandler::RegisterWrite* writeListBuffer = new CGSHandler::RegisterWrite[writeList.size()];
|
||||
|
@ -2314,9 +2314,8 @@ void CPS2OS::sc_GetMemorySize()
|
||||
|
||||
void CPS2OS::SysCallHandler()
|
||||
{
|
||||
|
||||
#ifdef PROFILE
|
||||
CProfiler::GetInstance().EndZone();
|
||||
CProfilerZone profilerZone(PROFILE_OTHERZONE);
|
||||
#endif
|
||||
|
||||
uint32 searchAddress = m_ee.m_State.nCOP0[CCOP_SCU::EPC];
|
||||
@ -2358,10 +2357,6 @@ void CPS2OS::SysCallHandler()
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef PROFILE
|
||||
CProfiler::GetInstance().BeginZone(PROFILE_EEZONE);
|
||||
#endif
|
||||
|
||||
m_ee.m_State.nHasException = 0;
|
||||
}
|
||||
|
||||
|
109
Source/PS2VM.cpp
109
Source/PS2VM.cpp
@ -66,6 +66,11 @@
|
||||
|
||||
#define VPU_LOG_BASE "./vpu_logs/"
|
||||
|
||||
#ifdef PROFILE
|
||||
#define PROFILE_EEZONE "EE"
|
||||
#define PROFILE_IOPZONE "IOP"
|
||||
#endif
|
||||
|
||||
namespace filesystem = boost::filesystem;
|
||||
|
||||
CPS2VM::CPS2VM()
|
||||
@ -84,8 +89,8 @@ CPS2VM::CPS2VM()
|
||||
, m_executor(m_EE, 0x20000000)
|
||||
, m_nStatus(PAUSED)
|
||||
, m_nEnd(false)
|
||||
, m_gs(NULL)
|
||||
, m_pad(NULL)
|
||||
, m_gs(NULL)
|
||||
, m_pad(NULL)
|
||||
, m_singleStepEe(false)
|
||||
, m_singleStepIop(false)
|
||||
, m_singleStepVu0(false)
|
||||
@ -97,7 +102,7 @@ CPS2VM::CPS2VM()
|
||||
, m_spuUpdateTicks(SPU_UPDATE_TICKS)
|
||||
, m_pCDROM0(NULL)
|
||||
, m_dmac(m_ram, m_spr, m_pVUMem0, m_EE)
|
||||
, m_gif(m_gs, m_ram, m_spr)
|
||||
, m_gif(m_gs, m_ram, m_spr)
|
||||
, m_sif(m_dmac, m_ram, m_iop.m_ram)
|
||||
, m_vif(m_gif, m_ram, m_spr, CVIF::VPUINIT(m_pMicroMem0, m_pVUMem0, &m_VU0), CVIF::VPUINIT(m_pMicroMem1, m_pVUMem1, &m_VU1))
|
||||
, m_intc(m_dmac)
|
||||
@ -135,7 +140,7 @@ CPS2VM::CPS2VM()
|
||||
CAppConfig::GetInstance().RegisterPreferenceInteger(PREF_PS2_FRAMESKIP, PREF_PS2_FRAMESKIP_DEFAULT);
|
||||
|
||||
m_iopOs = std::make_shared<CIopBios>(m_iop.m_cpu, m_iop.m_ram, PS2::IOP_RAM_SIZE);
|
||||
m_os = new CPS2OS(m_EE, m_ram, m_bios, m_gs, m_sif, *m_iopOs);
|
||||
m_os = new CPS2OS(m_EE, m_ram, m_bios, m_gs, m_sif, *m_iopOs);
|
||||
m_os->OnRequestInstructionCacheFlush.connect(boost::bind(&CPS2VM::FlushInstructionCache, this));
|
||||
m_os->OnRequestLoadExecutable.connect(boost::bind(&CPS2VM::ReloadExecutable, this, _1, _2));
|
||||
}
|
||||
@ -156,30 +161,30 @@ CPS2VM::~CPS2VM()
|
||||
|
||||
void CPS2VM::CreateGSHandler(const CGSHandler::FactoryFunction& factoryFunction)
|
||||
{
|
||||
if(m_gs != NULL) return;
|
||||
if(m_gs != NULL) return;
|
||||
m_mailBox.SendCall(bind(&CPS2VM::CreateGsImpl, this, factoryFunction), true);
|
||||
}
|
||||
|
||||
CGSHandler* CPS2VM::GetGSHandler()
|
||||
{
|
||||
return m_gs;
|
||||
return m_gs;
|
||||
}
|
||||
|
||||
void CPS2VM::DestroyGSHandler()
|
||||
{
|
||||
if(m_gs == NULL) return;
|
||||
if(m_gs == NULL) return;
|
||||
m_mailBox.SendCall(std::bind(&CPS2VM::DestroyGsImpl, this), true);
|
||||
}
|
||||
|
||||
void CPS2VM::CreatePadHandler(const CPadHandler::FactoryFunction& factoryFunction)
|
||||
{
|
||||
if(m_pad != NULL) return;
|
||||
if(m_pad != NULL) return;
|
||||
m_mailBox.SendCall(std::bind(&CPS2VM::CreatePadHandlerImpl, this, factoryFunction), true);
|
||||
}
|
||||
|
||||
void CPS2VM::DestroyPadHandler()
|
||||
{
|
||||
if(m_pad == NULL) return;
|
||||
if(m_pad == NULL) return;
|
||||
m_mailBox.SendCall(std::bind(&CPS2VM::DestroyPadHandlerImpl, this), true);
|
||||
}
|
||||
|
||||
@ -303,7 +308,7 @@ void CPS2VM::LoadDebugTags(const char* packageName)
|
||||
{
|
||||
std::string packagePath = MakeDebugTagsPackagePath(packageName);
|
||||
Framework::CStdStream stream(packagePath.c_str(), "rb");
|
||||
boost::scoped_ptr<Framework::Xml::CNode> document(Framework::Xml::CParser::ParseDocument(stream));
|
||||
boost::scoped_ptr<Framework::Xml::CNode> document(Framework::Xml::CParser::ParseDocument(stream));
|
||||
Framework::Xml::CNode* tagsNode = document->Select(TAGS_SECTION_TAGS);
|
||||
if(!tagsNode) return;
|
||||
m_EE.m_Functions.Unserialize(tagsNode, TAGS_SECTION_EE_FUNCTIONS);
|
||||
@ -500,9 +505,9 @@ void CPS2VM::ResetVM()
|
||||
m_intc.Reset();
|
||||
m_timer.Reset();
|
||||
|
||||
if(m_gs != NULL)
|
||||
if(m_gs != NULL)
|
||||
{
|
||||
m_gs->Reset();
|
||||
m_gs->Reset();
|
||||
}
|
||||
|
||||
m_os->Initialize();
|
||||
@ -553,7 +558,7 @@ void CPS2VM::DestroyVM()
|
||||
|
||||
void CPS2VM::SaveVMState(const char* sPath, unsigned int& result)
|
||||
{
|
||||
if(m_gs == NULL)
|
||||
if(m_gs == NULL)
|
||||
{
|
||||
printf("PS2VM: GS Handler was not instancied. Cannot save state.\r\n");
|
||||
result = 1;
|
||||
@ -576,7 +581,7 @@ void CPS2VM::SaveVMState(const char* sPath, unsigned int& result)
|
||||
archive.InsertFile(new CMemoryStateFile(STATE_MICROMEM1, m_pMicroMem1, PS2::MICROMEM1SIZE));
|
||||
|
||||
m_iop.SaveState(archive);
|
||||
m_gs->SaveState(archive);
|
||||
m_gs->SaveState(archive);
|
||||
m_dmac.SaveState(archive);
|
||||
m_intc.SaveState(archive);
|
||||
m_sif.SaveState(archive);
|
||||
@ -599,7 +604,7 @@ void CPS2VM::SaveVMState(const char* sPath, unsigned int& result)
|
||||
|
||||
void CPS2VM::LoadVMState(const char* sPath, unsigned int& result)
|
||||
{
|
||||
if(m_gs == NULL)
|
||||
if(m_gs == NULL)
|
||||
{
|
||||
printf("PS2VM: GS Handler was not instancied. Cannot load state.\r\n");
|
||||
result = 1;
|
||||
@ -624,7 +629,7 @@ void CPS2VM::LoadVMState(const char* sPath, unsigned int& result)
|
||||
archive.BeginReadFile(STATE_MICROMEM1 )->Read(m_pMicroMem1, PS2::MICROMEM1SIZE);
|
||||
|
||||
m_iop.LoadState(archive);
|
||||
m_gs->LoadState(archive);
|
||||
m_gs->LoadState(archive);
|
||||
m_dmac.LoadState(archive);
|
||||
m_intc.LoadState(archive);
|
||||
m_sif.LoadState(archive);
|
||||
@ -669,7 +674,7 @@ void CPS2VM::ResumeImpl()
|
||||
|
||||
void CPS2VM::DestroyImpl()
|
||||
{
|
||||
DELETEPTR(m_gs);
|
||||
DELETEPTR(m_gs);
|
||||
m_nEnd = true;
|
||||
}
|
||||
|
||||
@ -682,28 +687,28 @@ void CPS2VM::CreateGsImpl(const CGSHandler::FactoryFunction& factoryFunction)
|
||||
|
||||
void CPS2VM::DestroyGsImpl()
|
||||
{
|
||||
m_gs->Release();
|
||||
DELETEPTR(m_gs);
|
||||
m_gs->Release();
|
||||
DELETEPTR(m_gs);
|
||||
}
|
||||
|
||||
void CPS2VM::CreatePadHandlerImpl(const CPadHandler::FactoryFunction& factoryFunction)
|
||||
{
|
||||
m_pad = factoryFunction();
|
||||
m_pad = factoryFunction();
|
||||
RegisterModulesInPadHandler();
|
||||
}
|
||||
|
||||
void CPS2VM::DestroyPadHandlerImpl()
|
||||
{
|
||||
DELETEPTR(m_pad);
|
||||
DELETEPTR(m_pad);
|
||||
}
|
||||
|
||||
void CPS2VM::OnGsNewFrame()
|
||||
{
|
||||
m_frameNumber++;
|
||||
bool drawFrame = (m_frameSkip == 0) ? true : (m_frameNumber % (m_frameSkip + 1)) == 0;
|
||||
if(m_gs != NULL)
|
||||
if(m_gs != NULL)
|
||||
{
|
||||
m_gs->SetEnabled(drawFrame);
|
||||
m_gs->SetEnabled(drawFrame);
|
||||
}
|
||||
m_vif.SetEnabled(drawFrame);
|
||||
}
|
||||
@ -817,10 +822,10 @@ void CPS2VM::LoadBIOS()
|
||||
|
||||
void CPS2VM::RegisterModulesInPadHandler()
|
||||
{
|
||||
if(m_pad == NULL) return;
|
||||
if(m_pad == NULL) return;
|
||||
|
||||
m_pad->RemoveAllListeners();
|
||||
m_pad->InsertListener(m_iopOs->GetPadman());
|
||||
m_pad->RemoveAllListeners();
|
||||
m_pad->InsertListener(m_iopOs->GetPadman());
|
||||
m_pad->InsertListener(&m_iop.m_sio2);
|
||||
}
|
||||
|
||||
@ -856,7 +861,7 @@ void CPS2VM::FillFakeIopRam()
|
||||
uint32 CPS2VM::IOPortReadHandler(uint32 nAddress)
|
||||
{
|
||||
#ifdef PROFILE
|
||||
CProfiler::GetInstance().EndZone();
|
||||
CProfilerZone profilerZone(PROFILE_OTHERZONE);
|
||||
#endif
|
||||
|
||||
uint32 nReturn = 0;
|
||||
@ -882,9 +887,9 @@ uint32 CPS2VM::IOPortReadHandler(uint32 nAddress)
|
||||
}
|
||||
else if(nAddress >= 0x12000000 && nAddress <= 0x1200108C)
|
||||
{
|
||||
if(m_gs != NULL)
|
||||
if(m_gs != NULL)
|
||||
{
|
||||
nReturn = m_gs->ReadPrivRegister(nAddress);
|
||||
nReturn = m_gs->ReadPrivRegister(nAddress);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -892,17 +897,13 @@ uint32 CPS2VM::IOPortReadHandler(uint32 nAddress)
|
||||
printf("PS2VM: Read an unhandled IO port (0x%0.8X).\r\n", nAddress);
|
||||
}
|
||||
|
||||
#ifdef PROFILE
|
||||
CProfiler::GetInstance().BeginZone(PROFILE_EEZONE);
|
||||
#endif
|
||||
|
||||
return nReturn;
|
||||
}
|
||||
|
||||
uint32 CPS2VM::IOPortWriteHandler(uint32 nAddress, uint32 nData)
|
||||
{
|
||||
#ifdef PROFILE
|
||||
CProfiler::GetInstance().EndZone();
|
||||
CProfilerZone profilerZone(PROFILE_OTHERZONE);
|
||||
#endif
|
||||
|
||||
if(nAddress >= 0x10000000 && nAddress <= 0x1000183F)
|
||||
@ -937,9 +938,9 @@ uint32 CPS2VM::IOPortWriteHandler(uint32 nAddress, uint32 nData)
|
||||
}
|
||||
else if(nAddress >= 0x12000000 && nAddress <= 0x1200108C)
|
||||
{
|
||||
if(m_gs != NULL)
|
||||
if(m_gs != NULL)
|
||||
{
|
||||
m_gs->WritePrivRegister(nAddress, nData);
|
||||
m_gs->WritePrivRegister(nAddress, nData);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -947,10 +948,6 @@ uint32 CPS2VM::IOPortWriteHandler(uint32 nAddress, uint32 nData)
|
||||
printf("PS2VM: Wrote to an unhandled IO port (0x%0.8X, 0x%0.8X, PC: 0x%0.8X).\r\n", nAddress, nData, m_EE.m_State.nPC);
|
||||
}
|
||||
|
||||
#ifdef PROFILE
|
||||
CProfiler::GetInstance().BeginZone(PROFILE_EEZONE);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1123,6 +1120,9 @@ bool CPS2VM::IsEeIdle() const
|
||||
|
||||
void CPS2VM::EmuThread()
|
||||
{
|
||||
#ifdef PROFILE
|
||||
CProfiler::GetInstance().SetWorkThread();
|
||||
#endif
|
||||
while(1)
|
||||
{
|
||||
while(m_mailBox.IsPending())
|
||||
@ -1178,14 +1178,14 @@ void CPS2VM::EmuThread()
|
||||
m_intc.AssertLine(CINTC::INTC_LINE_VBLANK_START);
|
||||
m_iop.NotifyVBlankStart();
|
||||
|
||||
if(m_gs != NULL)
|
||||
if(m_gs != NULL)
|
||||
{
|
||||
m_gs->SetVBlank();
|
||||
m_gs->SetVBlank();
|
||||
}
|
||||
|
||||
if(m_pad != NULL)
|
||||
if(m_pad != NULL)
|
||||
{
|
||||
m_pad->Update(m_ram);
|
||||
m_pad->Update(m_ram);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1193,9 +1193,9 @@ void CPS2VM::EmuThread()
|
||||
m_vblankTicks += ONSCREEN_TICKS;
|
||||
m_intc.AssertLine(CINTC::INTC_LINE_VBLANK_END);
|
||||
m_iop.NotifyVBlankEnd();
|
||||
if(m_gs != NULL)
|
||||
if(m_gs != NULL)
|
||||
{
|
||||
m_gs->ResetVBlank();
|
||||
m_gs->ResetVBlank();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1206,10 +1206,21 @@ void CPS2VM::EmuThread()
|
||||
m_eeExecutionTicks += tickStep;
|
||||
m_iopExecutionTicks += tickStep / 8;
|
||||
|
||||
m_eeExecutionTicks -= ExecuteEe(m_singleStepEe ? 1 : m_eeExecutionTicks);
|
||||
{
|
||||
#ifdef PROFILE
|
||||
CProfilerZone profilerZone(PROFILE_EEZONE);
|
||||
#endif
|
||||
m_eeExecutionTicks -= ExecuteEe(m_singleStepEe ? 1 : m_eeExecutionTicks);
|
||||
}
|
||||
|
||||
unsigned int iopExecuted = m_iop.ExecuteCpu(m_singleStepIop ? 1 : m_iopExecutionTicks);
|
||||
m_iopExecutionTicks -= iopExecuted;
|
||||
unsigned int iopExecuted = 0;
|
||||
{
|
||||
#ifdef PROFILE
|
||||
CProfilerZone profilerZone(PROFILE_IOPZONE);
|
||||
#endif
|
||||
iopExecuted = m_iop.ExecuteCpu(m_singleStepIop ? 1 : m_iopExecutionTicks);
|
||||
m_iopExecutionTicks -= iopExecuted;
|
||||
}
|
||||
|
||||
int executed = tickStep;
|
||||
if(IsEeIdle() && m_iop.IsCpuIdle())
|
||||
|
@ -41,10 +41,6 @@ enum PS2VM_MSG
|
||||
PS2VM_MSG_RESET,
|
||||
};
|
||||
|
||||
#ifdef PROFILE
|
||||
#define PROFILE_EEZONE "EE"
|
||||
#endif
|
||||
|
||||
#define PREF_PS2_HOST_DIRECTORY ("ps2.host.directory")
|
||||
#define PREF_PS2_MC0_DIRECTORY ("ps2.mc0.directory")
|
||||
#define PREF_PS2_MC1_DIRECTORY ("ps2.mc1.directory")
|
||||
|
@ -1,12 +1,8 @@
|
||||
#include "Profiler.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
|
||||
#ifdef PROFILE
|
||||
|
||||
CProfiler::CProfiler() :
|
||||
m_OtherZone("Other")
|
||||
CProfiler::CProfiler()
|
||||
{
|
||||
|
||||
}
|
||||
@ -18,131 +14,94 @@ CProfiler::~CProfiler()
|
||||
|
||||
void CProfiler::BeginIteration()
|
||||
{
|
||||
m_nCurrentTime = clock();
|
||||
Reset();
|
||||
m_currentTime = clock();
|
||||
}
|
||||
|
||||
void CProfiler::EndIteration()
|
||||
{
|
||||
mutex::scoped_lock Lock(m_Mutex);
|
||||
|
||||
m_Stats.clear();
|
||||
|
||||
for(ZoneMap::const_iterator itZone = m_Zones.begin();
|
||||
itZone != m_Zones.end();
|
||||
itZone++)
|
||||
{
|
||||
m_Stats.push_back((*itZone));
|
||||
}
|
||||
|
||||
m_Stats.push_back(m_OtherZone);
|
||||
std::lock_guard<std::mutex> mutexLock(m_mutex);
|
||||
}
|
||||
|
||||
void CProfiler::BeginZone(const char* sName)
|
||||
void CProfiler::BeginZone(const char* name)
|
||||
{
|
||||
|
||||
clock_t nTime;
|
||||
nTime = clock();
|
||||
assert(std::this_thread::get_id() == m_workThreadId);
|
||||
|
||||
clock_t nTime = clock();
|
||||
|
||||
{
|
||||
mutex::scoped_lock Lock(m_Mutex);
|
||||
|
||||
CZone& Zone = GetCurrentZone();
|
||||
Zone.AddTime(nTime - m_nCurrentTime);
|
||||
|
||||
ZoneMap::iterator itZone;
|
||||
|
||||
itZone = m_Zones.find(sName);
|
||||
if(itZone == m_Zones.end())
|
||||
{
|
||||
string sZoneName(sName);
|
||||
m_Zones.insert(sZoneName, new CZone(sName));
|
||||
itZone = m_Zones.find(sName);
|
||||
}
|
||||
|
||||
m_ZoneStack.push_back(&(*itZone));
|
||||
std::lock_guard<std::mutex> mutexLock(m_mutex);
|
||||
AddTimeToCurrentZone(nTime - m_currentTime);
|
||||
m_zoneStack.push(name);
|
||||
}
|
||||
|
||||
m_nCurrentTime = clock();
|
||||
m_currentTime = clock();
|
||||
}
|
||||
|
||||
void CProfiler::EndZone()
|
||||
{
|
||||
clock_t nTime;
|
||||
|
||||
nTime = clock();
|
||||
assert(std::this_thread::get_id() == m_workThreadId);
|
||||
|
||||
clock_t nTime = clock();
|
||||
|
||||
{
|
||||
mutex::scoped_lock Lock(m_Mutex);
|
||||
std::lock_guard<std::mutex> mutexLock(m_mutex);
|
||||
|
||||
if(m_ZoneStack.size() == 0)
|
||||
if(m_zoneStack.size() == 0)
|
||||
{
|
||||
throw exception("Currently not inside any zone.");
|
||||
throw std::runtime_error("Currently not inside any zone.");
|
||||
}
|
||||
|
||||
CZone& Zone = GetCurrentZone();
|
||||
Zone.AddTime(nTime - m_nCurrentTime);
|
||||
|
||||
m_ZoneStack.pop_back();
|
||||
AddTimeToCurrentZone(nTime - m_currentTime);
|
||||
m_zoneStack.pop();
|
||||
}
|
||||
|
||||
m_nCurrentTime = clock();
|
||||
m_currentTime = clock();
|
||||
}
|
||||
|
||||
CProfiler::ZoneList CProfiler::GetStats()
|
||||
CProfiler::ZoneMap CProfiler::GetStats()
|
||||
{
|
||||
mutex::scoped_lock Lock(m_Mutex);
|
||||
|
||||
return m_Stats;
|
||||
std::lock_guard<std::mutex> mutexLock(m_mutex);
|
||||
return m_zones;
|
||||
}
|
||||
|
||||
void CProfiler::Reset()
|
||||
{
|
||||
mutex::scoped_lock Lock(m_Mutex);
|
||||
std::lock_guard<std::mutex> mutexLock(m_mutex);
|
||||
std::for_each(std::begin(m_zones), std::end(m_zones), [] (ZoneMap::value_type& zonePair) { zonePair.second = 0; });
|
||||
}
|
||||
|
||||
for(ZoneMap::iterator itZone = m_Zones.begin();
|
||||
itZone != m_Zones.end();
|
||||
itZone++)
|
||||
void CProfiler::SetWorkThread()
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
m_workThreadId = std::this_thread::get_id();
|
||||
#endif
|
||||
}
|
||||
|
||||
void CProfiler::AddTimeToCurrentZone(clock_t time)
|
||||
{
|
||||
std::string currentZoneName = (m_zoneStack.size() == 0) ? PROFILE_OTHERZONE : m_zoneStack.top();
|
||||
auto zoneIterator = m_zones.find(currentZoneName);
|
||||
if(zoneIterator == std::end(m_zones))
|
||||
{
|
||||
(*itZone).Reset();
|
||||
m_zones.insert(ZoneMap::value_type(currentZoneName, 0));
|
||||
zoneIterator = m_zones.find(currentZoneName);
|
||||
}
|
||||
zoneIterator->second += time;
|
||||
}
|
||||
|
||||
CProfiler::CZone& CProfiler::GetCurrentZone()
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//CProfilerZone
|
||||
|
||||
CProfilerZone::CProfilerZone(const char* name)
|
||||
: m_name(name)
|
||||
{
|
||||
if(m_ZoneStack.size() == 0)
|
||||
{
|
||||
return m_OtherZone;
|
||||
}
|
||||
else
|
||||
{
|
||||
return **(m_ZoneStack.rbegin());
|
||||
}
|
||||
CProfiler::GetInstance().BeginZone(name);
|
||||
}
|
||||
|
||||
CProfiler::CZone::CZone(const char* sName)
|
||||
CProfilerZone::~CProfilerZone()
|
||||
{
|
||||
m_sName = sName;
|
||||
m_nTime = 0;
|
||||
}
|
||||
|
||||
void CProfiler::CZone::AddTime(clock_t nTime)
|
||||
{
|
||||
m_nTime += nTime;
|
||||
}
|
||||
|
||||
const char* CProfiler::CZone::GetName() const
|
||||
{
|
||||
return m_sName.c_str();
|
||||
}
|
||||
|
||||
clock_t CProfiler::CZone::GetTime() const
|
||||
{
|
||||
return m_nTime;
|
||||
}
|
||||
|
||||
void CProfiler::CZone::Reset()
|
||||
{
|
||||
m_nTime = 0;
|
||||
CProfiler::GetInstance().EndZone();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,60 +1,61 @@
|
||||
#ifndef _PROFILER_H_
|
||||
#define _PROFILER_H_
|
||||
|
||||
#include <boost/ptr_container/ptr_map.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <ctime>
|
||||
#include <map>
|
||||
#include <stack>
|
||||
#include <thread>
|
||||
#include "Singleton.h"
|
||||
|
||||
#ifdef PROFILE
|
||||
|
||||
#define PROFILE_OTHERZONE "Other"
|
||||
|
||||
class CProfiler : public CSingleton<CProfiler>
|
||||
{
|
||||
public:
|
||||
typedef std::map<std::string, clock_t> ZoneMap;
|
||||
|
||||
friend CSingleton;
|
||||
|
||||
class CZone
|
||||
{
|
||||
public:
|
||||
CZone(const char*);
|
||||
void AddTime(clock_t);
|
||||
const char* GetName() const;
|
||||
clock_t GetTime() const;
|
||||
void Reset();
|
||||
|
||||
private:
|
||||
std::string m_sName;
|
||||
clock_t m_nTime;
|
||||
};
|
||||
|
||||
typedef std::list<CZone> ZoneList;
|
||||
|
||||
void BeginIteration();
|
||||
void EndIteration();
|
||||
|
||||
void BeginZone(const char*);
|
||||
void EndZone();
|
||||
|
||||
ZoneList GetStats();
|
||||
ZoneMap GetStats();
|
||||
void Reset();
|
||||
|
||||
void SetWorkThread();
|
||||
|
||||
private:
|
||||
typedef std::stack<std::string> ZoneStack;
|
||||
|
||||
CProfiler();
|
||||
virtual ~CProfiler();
|
||||
|
||||
CZone& GetCurrentZone();
|
||||
void AddTimeToCurrentZone(clock_t);
|
||||
|
||||
typedef boost::ptr_map<std::string, CZone> ZoneMap;
|
||||
typedef std::list<CZone*> ZoneStack;
|
||||
std::mutex m_mutex;
|
||||
clock_t m_currentTime;
|
||||
ZoneMap m_zones;
|
||||
ZoneStack m_zoneStack;
|
||||
|
||||
#ifdef _DEBUG
|
||||
std::thread::id m_workThreadId;
|
||||
#endif
|
||||
};
|
||||
|
||||
boost::mutex m_Mutex;
|
||||
CZone m_OtherZone;
|
||||
clock_t m_nCurrentTime;
|
||||
ZoneMap m_Zones;
|
||||
ZoneStack m_ZoneStack;
|
||||
ZoneList m_Stats;
|
||||
class CProfilerZone
|
||||
{
|
||||
public:
|
||||
CProfilerZone(const char*);
|
||||
~CProfilerZone();
|
||||
|
||||
private:
|
||||
const char* m_name;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -124,11 +124,6 @@ uint32 CSIF::ReceiveDMA5(uint32 srcAddress, uint32 size, uint32 unused, bool isT
|
||||
|
||||
uint32 CSIF::ReceiveDMA6(uint32 nSrcAddr, uint32 nSize, uint32 nDstAddr, bool isTagIncluded)
|
||||
{
|
||||
|
||||
#ifdef PROFILE
|
||||
CProfiler::GetInstance().BeginZone(PROFILE_SIFZONE);
|
||||
#endif
|
||||
|
||||
assert(!isTagIncluded);
|
||||
|
||||
//Humm, this is kinda odd, but it ors the address with 0x20000000
|
||||
@ -139,10 +134,6 @@ uint32 CSIF::ReceiveDMA6(uint32 nSrcAddr, uint32 nSize, uint32 nDstAddr, bool is
|
||||
//This should be the arguments for the call command
|
||||
//Just save the source address for later use
|
||||
m_nDataAddr = nSrcAddr;
|
||||
|
||||
#ifdef PROFILE
|
||||
CProfiler::GetInstance().EndZone();
|
||||
#endif
|
||||
return nSize;
|
||||
}
|
||||
else if(nDstAddr == CMD_RECVADDR)
|
||||
@ -190,10 +181,6 @@ uint32 CSIF::ReceiveDMA6(uint32 nSrcAddr, uint32 nSize, uint32 nDstAddr, bool is
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef PROFILE
|
||||
CProfiler::GetInstance().EndZone();
|
||||
#endif
|
||||
|
||||
return nSize;
|
||||
}
|
||||
else
|
||||
|
@ -118,7 +118,7 @@ uint32 CVIF::ProcessDMAPacket(unsigned int vpuNumber, uint32 address, uint32 qwc
|
||||
#endif
|
||||
|
||||
#ifdef PROFILE
|
||||
CProfiler::GetInstance().BeginZone(PROFILE_VIFZONE);
|
||||
CProfilerZone profilerZone(PROFILE_VIFZONE);
|
||||
#endif
|
||||
|
||||
m_stream[vpuNumber]->SetDmaParams(address, qwc * 0x10);
|
||||
@ -129,10 +129,6 @@ uint32 CVIF::ProcessDMAPacket(unsigned int vpuNumber, uint32 address, uint32 qwc
|
||||
|
||||
m_pVPU[vpuNumber]->ProcessPacket(*m_stream[vpuNumber]);
|
||||
|
||||
#ifdef PROFILE
|
||||
CProfiler::GetInstance().EndZone();
|
||||
#endif
|
||||
|
||||
uint32 remainingSize = m_stream[vpuNumber]->GetRemainingDmaTransferSize();
|
||||
assert((remainingSize & 0x0F) == 0);
|
||||
remainingSize /= 0x10;
|
||||
@ -201,12 +197,18 @@ bool CVIF::IsVu1WaitingForProgramEnd() const
|
||||
void CVIF::ExecuteVu0(bool singleStep)
|
||||
{
|
||||
if(!IsVu0Running()) return;
|
||||
#ifdef PROFILE
|
||||
CProfilerZone profilerZone(PROFILE_VIFZONE);
|
||||
#endif
|
||||
m_pVPU[0]->Execute(singleStep);
|
||||
}
|
||||
|
||||
void CVIF::ExecuteVu1(bool singleStep)
|
||||
{
|
||||
if(!IsVu1Running()) return;
|
||||
#ifdef PROFILE
|
||||
CProfilerZone profilerZone(PROFILE_VIFZONE);
|
||||
#endif
|
||||
m_pVPU[1]->Execute(singleStep);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user