Jump to content
  • Advertisement
Sign in to follow this  
BeanDog

Something better than Sleep(0)?

This topic is 4791 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm writing a multiplayer game, but although my question is in the context of such, it is more appropriate to this forum. In order to make my code more coherent, I decided that everyone, including the player whose computer is being used as server, needs to open some sockets to the server application to play the game. The server application is a Win32 console application that starts up when the game begins (for debugging purposes). So I have two applications running simultaneously that both need fairly consistent chunks of the processor time. At first, my server was hogging 98% of the CPU, since it does basically nothing but number-crunching. So, in the main loop of the server, I put the old coding classic:
Sleep(10);
I later tried reducing the value to 1 or 0, but it doesn't change the fact that Sleep() takes a seemingly random time between 0 and 500 milliseconds to return, which obviously seriously screws up my server. I have to have both of these processes running through their main loop at least several dozen times per second, without hogging 100% of the CPU when they don't need all that time. I'm at a loss. What do I do? ~BenDilts( void );

Share this post


Link to post
Share on other sites
Advertisement
I never use Sleep for that purpose. As far as I know, if you are running your Message Pump, windows will automatically share the processor with other programs and with yours without you putting any Sleeps in the loop. I wouldn't go by the 98% that is stated in the Task manager because in a constant loop, you get 100% CPU usage, but 2% in this case probably went to the Task Manager itself processing your clicks to see the number in the first place.

Share this post


Link to post
Share on other sites
I made the server a console application in this instance for easy output of diagnostics that were easy to read. Console applications don't exactly have the same metaphor of a message pump, unless I'm seriously mistaken. Should I recreate my console app as a regular Win32 project, or is there some hack I could do in the meantime?

Update: I created an invisible window in the server application and now run a message pump on it during the server's main loop. But this code:

if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}

sometimes takes over 1/4 of a second to complete. I figure it's because the window is running in the background (not focused). It appears that this is sort of the case with a console window, as well (longer time between timeslices).



~BenDilts( void );

[Edited by - BeanDog on October 6, 2005 11:14:23 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by BeanDog
I later tried reducing the value to 1 or 0, but it doesn't change the fact that Sleep() takes a seemingly random time between 0 and 500 milliseconds to return, which obviously seriously screws up my server.

I have to have both of these processes running through their main loop at least several dozen times per second, without hogging 100% of the CPU when they don't need all that time.
So do both processes have a sleep(0) in them? If not then obviously your other process is stealing away time from this one at every opportunity. Sleep wouldn't take very long if there wasn't much else that really needed to be done.

If a single delay being 500ms long screws up your server then you may have a design problem. You shouldn't be relying on getting perfectly regular amounts of CPU time. If it does, you simply compensate. It can quite easily happen once in a while if you get a few page faults, because you have other apps open too.

So when it 'screws up', what exactly happens?

Share this post


Link to post
Share on other sites
Nothing too drastic happens--The players just jump positions drastically. It wouldn't be a problem if it happened a couple times an hour, but it happens about every 2-3 seconds.



~BenDilts( void );

Share this post


Link to post
Share on other sites
Problem isolated: This is not an issue when I don't run my program in the integrated debugger. I guess the IDE is sucking down too much CPU. Sorry for the trouble, guys. It's going to be a pain to debug this w/o the integrated debugger...



~BenDilts( void );

Share this post


Link to post
Share on other sites
Might I suggest an appropriate fix would be a fixed timestep. Then you could just run as many steps to "catch up" to the current time as necessary, and only run your Sleep() function when you have caught up (so you don't sleep when your program is lagging).

Because your time steps are fixed, they cannot grow extreemly long when your application is waiting for Sleep to return (or for something to page, or some other process).

Although you'll need a "bailout" method if you end up many milliseconds "late". You may also need some interpolation (particularly in the client).


Article worth reading, about network timing (about physics, but the theory applies to anything at all).

Share this post


Link to post
Share on other sites
Quote:
Original post by BeanDog
This is not an issue when I don't run my program in the integrated debugger. I guess the IDE is sucking down too much CPU. Sorry for the trouble, guys. It's going to be a pain to debug this w/o the integrated debugger...


Quick question: Are you handling a lot of exceptions at any point? I recently made a .net application in MSVC2005 Express Beta and when I had a lot of handled exceptions the program would slow to a crawl when attached to a debugger, but run fine otherwise. By preempting the error condition (putting in "if(wouldHaveError) { handleError(); } else { try { do(); } catch(System::Exception^) { handleError();} }"), it would run fine in the debugger too.

Now I don't know if it was because of 2005, .net, or simply exceptions running through a debugger, so I just thought I'd throw that out there as something to consider.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Your problem is that you need to give relief to the system. Sleep() does not do this, you need something like

::WaitForSingleObject( , ) ;

This will give relief to the system and let other threads and processes run.

Share this post


Link to post
Share on other sites
Quote:
Original post by Anonymous Poster
Your problem is that you need to give relief to the system. Sleep() does not do this, you need something like

::WaitForSingleObject( , ) ;

This will give relief to the system and let other threads and processes run.
Other threads and processes most certainly can run when your program calls Sleep()!
Perhaps you're thinking of MsgWaitForSingleObject which allows even the current thread to process messages as well, though that can cause reentrancy issues.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!