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:
Jake.Stine 2010-01-26 13:06:53 +00:00
parent c455ea38e5
commit 2dfad2fb24
7 changed files with 71 additions and 53 deletions

View File

@ -20,7 +20,7 @@
#include <ShTypes.h> #include <ShTypes.h>
static LARGE_INTEGER lfreq; static __aligned16 LARGE_INTEGER lfreq;
void InitCPUTicks() void InitCPUTicks()
{ {

View File

@ -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 );

View File

@ -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;

View File

@ -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;
} }

View File

@ -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

View File

@ -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;

View File

@ -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",