Archived

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

kordova

100% cpu cycle issue

Recommended Posts

I'm looking through a friend's source (I believe he originally based it from someone's book?) as he's using up 100% of his cpu cycles when running a very simple app. I'm certain it comes from this chunk as when I added the "else { Sleep(iTickTrigger ... " lines it dropped significantly. Anyway, is this the best way to handle it? It seems so to me but I don't want to misinform. Thanks ahead.
    
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  PSTR szCmdLine, int iCmdShow)
{
  MSG         msg;
  static int  iTickTrigger = 0;
  int         iTickCount;

  if (GameInitialize(hInstance))
  {
    // Initialize the game engine

    if (!GameEngine::GetEngine()->Initialize(iCmdShow))
      return FALSE;

    // Enter the main message loop

    while (TRUE)
    {
      if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
      {
        // Process the message

        if (msg.message == WM_QUIT)
          break;
        TranslateMessage(&msg);
        DispatchMessage(&msg);
      }
      else
      {
        // Make sure the game engine isn't sleeping

        if (!GameEngine::GetEngine()->GetSleep())
        {
          // Check the tick count to see if a game cycle has elapsed

          iTickCount = GetTickCount();
          if (iTickCount > iTickTrigger)
          {
            iTickTrigger = iTickCount +
              GameEngine::GetEngine()->GetFrameDelay();
            GameCycle();
          }
          else {
            Sleep((iTickTrigger-iTickCount));
          }
        }
      }
    }
    return (int)msg.wParam;
  }

  // End the game

  GameEnd();

  return TRUE;
}
    
[edited by - kordova on May 3, 2003 2:34:42 PM]

Share this post


Link to post
Share on other sites
A game usually uses all the CPU power available so a usage of 100% is absolutetly normal (look at commong game and judge yourself). It draws as many FPS as possible so it should be using maximum CPU.

hope that helped,
cya,
Phil

Visit Rarebyte!
and no!, there are NO kangaroos in Austria (I got this question a few times over in the states )

Share this post


Link to post
Share on other sites
Yeah, but I received 100% cpu when i set his global fps to 1. I''m pretty sure that it sits in an infinite loop that only calls the "gamecycle" when the determined time has elapsed, though it continues to loop even when theres many hundred milliseconds when there should be no activity. My only concern with my approach is that peekmsg won''t be hit very frequently though that may not matter (?)

Share this post


Link to post
Share on other sites
edit: upon reading all the code, I have no idea what you're attempting to do, but I'm fairly certain there's an easier way.

You can call Sleep() each frame to relinquish some CPU time to other processes. However, even if you only call Sleep(0) (the parameter is the number of milliseconds to give up), your maximum framerate will be 100, since Sleep is only accurate to about 10ms. So, you can either live with 100% usage, limit your FPS to 100, or come up with a creative way to call Sleep(10) every X number of frames. You get the idea.

Later,
ZE.

//email me.//zealouselixir software.//msdn.//n00biez.//
miscellaneous links


[edited by - zealouselixir on May 3, 2003 2:50:01 PM]

Share this post


Link to post
Share on other sites
Well a process should use as much CPU time as needed when it is in the foreground as long as it is doing meaningful work (i.e. not just spinning endlessly in a tight loop.)

Share this post


Link to post
Share on other sites
Ok thats what I thought. Is this an ok way to deal with the current setup:

WinMain
1. Initialize Windows etc (if any problems exit)
2. While (TRUE)
a. peekmsg
else
b. if game not sleeping (deactivated, minimized etc)
1. if enough time has elapsed
a. call engine work function
else
b. sleep for time between current and needed elapsed

Not sure if you can follow that, but that's the best an understanding I can get from this. The only thing I've added is the sleep portion and again im pretty sure if i change something in here it should make the difference. Thanks again all.

[edited by - kordova on May 3, 2003 3:41:24 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by ZealousElixir
edit : upon reading all the code, I have no idea what you''re attempting to do, but I''m fairly certain there''s an easier way.



Switch between GetMessage and PeekMessage when you receive WM_ACTIVATEAPP.

MSN

Share this post


Link to post
Share on other sites
also, because of the minimum sleep time on windows ... you will want to pad your "b. sleep for time between current and needed elapsed" so that if this number is below a certain threshold, don''t sleep anyway.

Share this post


Link to post
Share on other sites
Xao wrote:
also, because of the minimum sleep time on windows


Just use Sleep(0), which will only yield the cpu time to threads of equal or higher priority....

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
If you''re on a laptop with SpeedStep CPU, the Windows kernel will "helpfully" reduce the speed of the CPU if you call Sleep(). So calling that between each frame will cause jerkiness.

All games I know of just sit in a tight PeekMessage() loop, and step/render when PeekMessage returns 0 (or, if they want a fixed frame rate, just re-call PeekMessage()). As the poster said, you can switch to GetMessage() when you''re in the background, and post a WM_TIMER to keep the game moving forward a bit if necessary.

Don''t trust WM_TIMER to be accurate enough for rendering frames, though.

Share this post


Link to post
Share on other sites
quote:
Original post by kordova

WinMain
1. Initialize Windows etc (if any problems exit)
2. While (TRUE)
a. peekmsg
else
b. if game not sleeping (deactivated, minimized etc)
1. if enough time has elapsed
a. call engine work function
else
b. sleep for time between current and needed elapsed




Try these:


WinMain
1. Initialize Windows etc (if any problems exit)
2. While (TRUE)
if peekmsg
- Translate & dispatch msg
else if game not sleeping (paused, minimized etc)
- enter per frame game loop
else
- ::WaitMessage();

Share this post


Link to post
Share on other sites
quote:
Original post by kordova
What is WaitMessage()?


quote:
From MSDN
The WaitMessage function yields control to other threads when a thread has no other messages in its message queue. The WaitMessage function suspends the thread and does not return until a new message is placed in the thread''s message queue.





Qui fut tout, et qui ne fut rien
Invader''s Realm

Share this post


Link to post
Share on other sites
WaitMessage is the correct way of reducing your CPU cycle down to 0% (if your app is not in focus). Respond to WM_ACTIVATEAPP, when your app lost its focus, call WaitMessage().

If your game is running and in focus, 100% CPU usage is normal.


Current project: A puzzle game.
% completed: ~10%
Status: Active.

Share this post


Link to post
Share on other sites