Archived

This topic is now archived and is closed to further replies.

Wisconsin

CPU Usage

Recommended Posts

Typically games only run when they are "activated", i.e. the window that is at the forefront. IN which case they don''t use any CPU cycles when they are minimized or some other app is active.

Share this post


Link to post
Share on other sites
But, as is the case in AOE2, what happens then? as its not in focus but still running.. i would presume still runs at full speed as most processors can cope with it today. Or I suppose you could not call unneeded functions/pause unneeded threads like the sound, rendering, input and what not when the focus is taken away, and still keep other threads such as networking and the main game loop still ticking over at full speed so the game ''appears'' to have still been running at normal speed when they resume play. And as for windowed mode.. I wouldn''t attempt to sacrifice my games speed because they want to run it in a window, it must be deemed illegal by some unwritten law

Share this post


Link to post
Share on other sites
If you run flat-out you consume 100% of the CPU time.
To be win-friendly, somewhere in every thread you must sleep. Even a Sleep(0) is better than nothing (this gives-up the remainder of the current time-slice to another thread if one is available to run and would pre-empt you at the next slice, otherwise it comes right back to you).

If the user alt-tab's out you should stop rendering altogether (why render? you can't display it!), and throttle the frame-rate if you lose focus.

Some companies (either Verant or Sony or both) don't support this recommended behavior because it gives them a false sense of security - the trivial increase in difficulty to hack is not worth the inconvenience a-mon-avis.


You wouldn't need to pause networking or audio threads or the like because they are generally event driven and consume minimal resources. If it's a MP game you kinda need to keep responding to network events and keep the AI going, but even there you can skip the rendering which is where a good portion of the CPU goes. If it's SP, pause the game and throttle the renderer.

[edit: corrected spelling & grammer mistakes, I'd think I was drunk re-reading this]

[edited by - Magmai Kai Holmlor on May 1, 2002 11:52:08 PM]

Share this post


Link to post
Share on other sites
When you have the input focus you get a priority boost. So if they switch to another application and that application needs CPU it is going to get more than you without you doing anything. If they are calculating pi to a million places you are most likely going to slow them down, but with most applications memory is going to matter more. Think about what data you need while minimized and try to pack that all as closely together as possible. That will let your working set drop to as small a size as possible when you are minimized. Swapping in a bunch of pages everytime you run will do far more to interfer with another application than your CPU usage. If you want to appeal to the guy that is running 30 applications at once on his 200mhz Pentium with 32mb of ram then that is going to do the most to make you his favorite programmer.

Share this post


Link to post
Share on other sites
If you're running single threaded, or the thread that you're thinking about making sleep it the one with the message loop, I'd use

MsgWaitForMultipleObjects( 0,0,FALSE,INFINITE,QS_ALLINPUT );

rather than

Sleep( ms );

so you wake up immediately when WM_ACTIVATE is sent back, and you don't have to calculate how long to wait.

Here's my WM_ACTIVATE handler for an example:

    
void TWindow::OnActivateApp( WPARAM wParam,LPARAM lParam )
{
m_fActive = (wParam != 0);

m_fActive = true;

if( !m_fActive )
{
if( m_fFullScreen )
ShowWindow( m_hwnd,SW_MINIMIZE );

SetFullScreen( false );

// set alertable wait state and consume no CPU cycles

MsgWaitForMultipleObjects( 0,0,FALSE,INFINITE,QS_ALLINPUT );
}
else
SetFullScreen( m_fFullScreen && !m_fInitialShowing );
}
//--------------------------------------------------------------------------------------------------



This won't help with networking or sound, but they're generally done in other threads anywhoo? Being just a graphics guy, though, this is all I need. I shut down completely - no cycles at all. Another option would be to run at half the frame rate and only update AI, networking, and/or sound (as was previously suggested). Since networking and sound are generally in another thread, the easiest way to do this is like this, I might imagine (off the top of my head):

  
inline void Delay( const unsigned ms )
{
MsgWaitForMultipleObjects( 0,0,FALSE,ms,QS_ALLINPUT );
}
//---------------------------------------------------------------------------


void TApplication::MainLoop( void )
{
static const DWORD sc_dwFPS = 60;
static const DWORD sc_dwTimePerFrame = 1000/sc_dwFPS;

static DWORD s_dwLastStartTime = GetTime();
DWORD dwStartTime = GetTime();

DWORD dwTimeForThisFrame = sc_dwTimePerFrame;
if( m_fActive )
{
DoAI();
Render();
}
else
{
DoAI();
dwTimeForThisFrame *= 2;
}

// sync to fps (or half fps in not active)

DWORD dwElapsedTime = GetTime() - dwStartTime - s_dwLastStartTime;
if( dwElapsedTime < dwTimeForThisFrame )
{
DWORD dwTimeLeft = dwTimeForThisFrame - dwElapsedTime
Delay( dwTimeLeft );
}
s_dwLastStartTime = dwStartTime;
}


[edited by - Succinct on May 1, 2002 8:38:00 PM]

Share this post


Link to post
Share on other sites