mirror of https://github.com/PCSX2/pcsx2.git
Improved CPU usage and fps stats.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2523 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
c455ea38e5
commit
2dfad2fb24
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
#include <ShTypes.h>
|
#include <ShTypes.h>
|
||||||
|
|
||||||
static LARGE_INTEGER lfreq;
|
static __aligned16 LARGE_INTEGER lfreq;
|
||||||
|
|
||||||
void InitCPUTicks()
|
void InitCPUTicks()
|
||||||
{
|
{
|
||||||
|
|
|
@ -64,7 +64,7 @@ u64 Threading::GetThreadCpuTime()
|
||||||
{
|
{
|
||||||
FileTimeSucks user, kernel;
|
FileTimeSucks user, kernel;
|
||||||
FILETIME dummy;
|
FILETIME dummy;
|
||||||
GetThreadTimes( GetCurrentThread(), &dummy, &dummy, &user.filetime, &kernel.filetime );
|
GetThreadTimes( GetCurrentThread(), &dummy, &dummy, &kernel.filetime, &user.filetime );
|
||||||
return user.u64time + kernel.u64time;
|
return user.u64time + kernel.u64time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,10 +80,7 @@ u64 Threading::PersistentThread::GetCpuTime() const
|
||||||
FileTimeSucks user, kernel;
|
FileTimeSucks user, kernel;
|
||||||
FILETIME dummy;
|
FILETIME dummy;
|
||||||
|
|
||||||
// Note: Vista and Win7 need only THREAD_QUERY_LIMITED_INFORMATION (XP and 2k need more),
|
if( GetThreadTimes( (HANDLE)m_native_handle, &dummy, &dummy, &kernel.filetime, &user.filetime ) )
|
||||||
// however we own our process threads, so shouldn't matter in any case...
|
|
||||||
|
|
||||||
if( GetThreadTimes( (HANDLE)m_native_handle, &dummy, &dummy, &user.filetime, &kernel.filetime ) )
|
|
||||||
return user.u64time + kernel.u64time;
|
return user.u64time + kernel.u64time;
|
||||||
|
|
||||||
return 0; // thread prolly doesn't exist anymore.
|
return 0; // thread prolly doesn't exist anymore.
|
||||||
|
@ -91,6 +88,9 @@ u64 Threading::PersistentThread::GetCpuTime() const
|
||||||
|
|
||||||
void Threading::PersistentThread::_platform_specific_OnStartInThread()
|
void Threading::PersistentThread::_platform_specific_OnStartInThread()
|
||||||
{
|
{
|
||||||
|
// OpenThread Note: Vista and Win7 need only THREAD_QUERY_LIMITED_INFORMATION (XP and 2k need more),
|
||||||
|
// however we own our process threads, so shouldn't matter in any case...
|
||||||
|
|
||||||
m_native_id = (uptr)GetCurrentThreadId();
|
m_native_id = (uptr)GetCurrentThreadId();
|
||||||
m_native_handle = (uptr)OpenThread( THREAD_QUERY_INFORMATION, false, (DWORD)m_native_id );
|
m_native_handle = (uptr)OpenThread( THREAD_QUERY_INFORMATION, false, (DWORD)m_native_id );
|
||||||
|
|
||||||
|
|
|
@ -327,7 +327,7 @@ struct pxAppResources
|
||||||
ScopedPtr<RecentIsoManager> RecentIsoList;
|
ScopedPtr<RecentIsoManager> RecentIsoList;
|
||||||
|
|
||||||
pxAppResources();
|
pxAppResources();
|
||||||
~pxAppResources() throw() { }
|
virtual ~pxAppResources() throw() { }
|
||||||
};
|
};
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
|
@ -340,8 +340,6 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
u64 m_fpsqueue[FramerateQueueDepth];
|
u64 m_fpsqueue[FramerateQueueDepth];
|
||||||
u64 m_fpsqueue_tally;
|
|
||||||
u64 m_ticks_lastframe;
|
|
||||||
int m_fpsqueue_writepos;
|
int m_fpsqueue_writepos;
|
||||||
uint m_initpause;
|
uint m_initpause;
|
||||||
|
|
||||||
|
|
|
@ -195,39 +195,38 @@ void Pcsx2App::PadKeyDispatch( const keyEvent& ev )
|
||||||
|
|
||||||
void FramerateManager::Reset()
|
void FramerateManager::Reset()
|
||||||
{
|
{
|
||||||
memzero( m_fpsqueue );
|
//memzero( m_fpsqueue );
|
||||||
m_initpause = FramerateQueueDepth;
|
m_initpause = FramerateQueueDepth;
|
||||||
m_fpsqueue_tally = 0;
|
|
||||||
m_fpsqueue_writepos = 0;
|
m_fpsqueue_writepos = 0;
|
||||||
|
|
||||||
|
for( int i=0; i<FramerateQueueDepth; ++i )
|
||||||
|
m_fpsqueue[i] = GetCPUTicks();
|
||||||
|
|
||||||
Resume();
|
Resume();
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
void FramerateManager::Resume()
|
void FramerateManager::Resume()
|
||||||
{
|
{
|
||||||
m_ticks_lastframe = GetCPUTicks();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramerateManager::DoFrame()
|
void FramerateManager::DoFrame()
|
||||||
{
|
{
|
||||||
++m_FrameCounter;
|
++m_FrameCounter;
|
||||||
|
|
||||||
u64 curtime = GetCPUTicks();
|
|
||||||
u64 elapsed_time = curtime - m_ticks_lastframe;
|
|
||||||
m_ticks_lastframe = curtime;
|
|
||||||
|
|
||||||
m_fpsqueue_tally += elapsed_time;
|
|
||||||
m_fpsqueue_tally -= m_fpsqueue[m_fpsqueue_writepos];
|
|
||||||
|
|
||||||
m_fpsqueue[m_fpsqueue_writepos] = elapsed_time;
|
|
||||||
m_fpsqueue_writepos = (m_fpsqueue_writepos + 1) % FramerateQueueDepth;
|
m_fpsqueue_writepos = (m_fpsqueue_writepos + 1) % FramerateQueueDepth;
|
||||||
if( m_initpause > 0 ) --m_initpause;
|
m_fpsqueue[m_fpsqueue_writepos] = GetCPUTicks();
|
||||||
|
|
||||||
|
// intentionally leave 1 on the counter here, since ultimately we want to divide the
|
||||||
|
// final result (in GetFramerate() by QueueDepth-1.
|
||||||
|
if( m_initpause > 1 ) --m_initpause;
|
||||||
}
|
}
|
||||||
|
|
||||||
double FramerateManager::GetFramerate() const
|
double FramerateManager::GetFramerate() const
|
||||||
{
|
{
|
||||||
if( m_initpause > (FramerateQueueDepth/2) ) return 0.0;
|
if( m_initpause > (FramerateQueueDepth/2) ) return 0.0;
|
||||||
u32 ticks_per_frame = m_fpsqueue_tally / (FramerateQueueDepth-m_initpause);
|
const u64 delta = m_fpsqueue[m_fpsqueue_writepos] - m_fpsqueue[(m_fpsqueue_writepos + 1) % FramerateQueueDepth];
|
||||||
|
const u32 ticks_per_frame = (u32)(delta / (FramerateQueueDepth-m_initpause));
|
||||||
return (double)GetTickFrequency() / (double)ticks_per_frame;
|
return (double)GetTickFrequency() / (double)ticks_per_frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,17 +24,35 @@
|
||||||
|
|
||||||
#include "GS.h"
|
#include "GS.h"
|
||||||
|
|
||||||
|
void AllThreeThreads::LoadWithCurrentTimes()
|
||||||
|
{
|
||||||
|
ee = GetCoreThread().GetCpuTime();
|
||||||
|
gs = GetMTGS().GetCpuTime();
|
||||||
|
ui = GetThreadCpuTime();
|
||||||
|
update = GetCPUTicks();
|
||||||
|
}
|
||||||
|
|
||||||
|
AllThreeThreads AllThreeThreads::operator-( const AllThreeThreads& right ) const
|
||||||
|
{
|
||||||
|
AllThreeThreads retval;
|
||||||
|
|
||||||
|
retval.ee = ee - right.ee;
|
||||||
|
retval.gs = gs - right.gs;
|
||||||
|
retval.ui = ui - right.ui;
|
||||||
|
retval.update = update - right.update;
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
DefaultCpuUsageProvider::DefaultCpuUsageProvider()
|
DefaultCpuUsageProvider::DefaultCpuUsageProvider()
|
||||||
{
|
{
|
||||||
m_lasttime_ee = GetCoreThread().GetCpuTime();
|
|
||||||
m_lasttime_gs = GetMTGS().GetCpuTime();
|
|
||||||
m_lasttime_ui = GetThreadCpuTime();
|
|
||||||
|
|
||||||
m_lasttime_update = GetCPUTicks();
|
|
||||||
|
|
||||||
m_pct_ee = 0;
|
m_pct_ee = 0;
|
||||||
m_pct_gs = 0;
|
m_pct_gs = 0;
|
||||||
m_pct_ui = 0;
|
m_pct_ui = 0;
|
||||||
|
m_writepos = 0;
|
||||||
|
|
||||||
|
for( int i=0; i<QueueDepth; ++i )
|
||||||
|
m_queue[i].LoadWithCurrentTimes();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DefaultCpuUsageProvider::IsImplemented() const
|
bool DefaultCpuUsageProvider::IsImplemented() const
|
||||||
|
@ -44,25 +62,19 @@ bool DefaultCpuUsageProvider::IsImplemented() const
|
||||||
|
|
||||||
void DefaultCpuUsageProvider::UpdateStats()
|
void DefaultCpuUsageProvider::UpdateStats()
|
||||||
{
|
{
|
||||||
u64 curtime = GetCPUTicks();
|
// Measure deltas between the first and last positions in the ring buffer:
|
||||||
u64 delta = curtime - m_lasttime_update;
|
|
||||||
if( delta < (GetTickFrequency() / 16) ) return;
|
|
||||||
|
|
||||||
u64 curtime_ee = GetCoreThread().GetCpuTime();
|
AllThreeThreads& newone( m_queue[m_writepos] );
|
||||||
u64 curtime_gs = GetMTGS().GetCpuTime();
|
newone.LoadWithCurrentTimes();
|
||||||
u64 curtime_ui = GetThreadCpuTime();
|
m_writepos = (m_writepos+1) & (QueueDepth-1);
|
||||||
|
const AllThreeThreads deltas( newone - m_queue[m_writepos] );
|
||||||
|
|
||||||
// get the real time passed, scaled to the Thread's tick frequency.
|
// get the real time passed, scaled to the Thread's tick frequency.
|
||||||
u64 timepass = (delta * GetThreadTicksPerSecond()) / GetTickFrequency();
|
u64 timepass = (deltas.update * GetThreadTicksPerSecond()) / GetTickFrequency();
|
||||||
|
|
||||||
m_pct_ee = ((curtime_ee - m_lasttime_ee) * 100) / timepass;
|
m_pct_ee = (deltas.ee * 100) / timepass;
|
||||||
m_pct_gs = ((curtime_gs - m_lasttime_gs) * 100) / timepass;
|
m_pct_gs = (deltas.gs * 100) / timepass;
|
||||||
m_pct_ui = ((curtime_ui - m_lasttime_ui) * 100) / timepass;
|
m_pct_ui = (deltas.ui * 100) / timepass;
|
||||||
|
|
||||||
m_lasttime_update = curtime;
|
|
||||||
m_lasttime_ee = curtime_ee;
|
|
||||||
m_lasttime_gs = curtime_gs;
|
|
||||||
m_lasttime_ui = curtime_ui;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int DefaultCpuUsageProvider::GetEEcorePct() const
|
int DefaultCpuUsageProvider::GetEEcorePct() const
|
||||||
|
|
|
@ -45,15 +45,24 @@ public:
|
||||||
virtual int GetGuiPct() const { return m_Implementation->GetGuiPct(); }
|
virtual int GetGuiPct() const { return m_Implementation->GetGuiPct(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct AllThreeThreads
|
||||||
|
{
|
||||||
|
u64 ee, gs, ui;
|
||||||
|
u64 update;
|
||||||
|
|
||||||
|
void LoadWithCurrentTimes();
|
||||||
|
AllThreeThreads operator-( const AllThreeThreads& right ) const;
|
||||||
|
};
|
||||||
|
|
||||||
class DefaultCpuUsageProvider : public BaseCpuUsageProvider
|
class DefaultCpuUsageProvider : public BaseCpuUsageProvider
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
static const uint QueueDepth = 4;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
u64 m_lasttime_ee;
|
AllThreeThreads m_queue[QueueDepth];
|
||||||
u64 m_lasttime_gs;
|
|
||||||
u64 m_lasttime_ui;
|
|
||||||
|
|
||||||
u64 m_lasttime_update;
|
|
||||||
|
|
||||||
|
uint m_writepos;
|
||||||
u32 m_pct_ee;
|
u32 m_pct_ee;
|
||||||
u32 m_pct_gs;
|
u32 m_pct_gs;
|
||||||
u32 m_pct_ui;
|
u32 m_pct_ui;
|
||||||
|
|
|
@ -271,14 +271,14 @@ wxStaticText* GSFrame::GetLabel_OutputDisabled() const
|
||||||
|
|
||||||
void GSFrame::CoreThread_OnResumed()
|
void GSFrame::CoreThread_OnResumed()
|
||||||
{
|
{
|
||||||
m_timer_UpdateTitle.Start( 333 );
|
m_timer_UpdateTitle.Start( 275 );
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSFrame::CoreThread_OnSuspended()
|
void GSFrame::CoreThread_OnSuspended()
|
||||||
{
|
{
|
||||||
// Could stop the timer outright here, tho no harm in having an occasional
|
// Could stop the timer outright here, tho no harm in having an occasional
|
||||||
// update here or there, just in case some state info changes while emu is suspended.
|
// update here or there, just in case some state info changes while emu is suspended.
|
||||||
m_timer_UpdateTitle.Start( 2000 );
|
m_timer_UpdateTitle.Start( 333 );
|
||||||
}
|
}
|
||||||
|
|
||||||
// overrides base Show behavior.
|
// overrides base Show behavior.
|
||||||
|
@ -301,7 +301,7 @@ bool GSFrame::Show( bool shown )
|
||||||
if( wxStaticText* label = GetLabel_OutputDisabled() )
|
if( wxStaticText* label = GetLabel_OutputDisabled() )
|
||||||
label->Show( EmuConfig.GS.DisableOutput );
|
label->Show( EmuConfig.GS.DisableOutput );
|
||||||
|
|
||||||
m_timer_UpdateTitle.Start( 333 );
|
m_timer_UpdateTitle.Start( 275 );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -350,7 +350,7 @@ void GSFrame::OnUpdateTitle( wxTimerEvent& evt )
|
||||||
if( m_CpuUsage.IsImplemented() )
|
if( m_CpuUsage.IsImplemented() )
|
||||||
{
|
{
|
||||||
m_CpuUsage.UpdateStats();
|
m_CpuUsage.UpdateStats();
|
||||||
cpuUsage = wxsFormat( L" | EE: %d%% | GS: %d%%", m_CpuUsage.GetEEcorePct(), m_CpuUsage.GetGsPct() );
|
cpuUsage = wxsFormat( L" | EE: %d%% | GS: %d%% | UI: %d%%", m_CpuUsage.GetEEcorePct(), m_CpuUsage.GetGsPct(), m_CpuUsage.GetGuiPct() );
|
||||||
}
|
}
|
||||||
|
|
||||||
SetTitle( wxsFormat( L"%s | Limiter: %s | fps: %2.02f%s",
|
SetTitle( wxsFormat( L"%s | Limiter: %s | fps: %2.02f%s",
|
||||||
|
|
Loading…
Reference in New Issue