Thread: How to relinquish processor cycles in wait functions

  1. #1
    Counter-Strike Master
    Join Date
    Dec 2002
    Posts
    38

    Question How to relinquish processor cycles in wait functions

    I'm trying to find an effective and accurate way for synching my framerate. If I use something like this:

    Code:
    while((curr_time - start_time) < 33)
        ; //wait and do nothing
    then it will eat up 100% of the computer's processor time and cause the processor to heat up. I've also tried using the sleep function from the Win32 API:

    Code:
    Sleep(33);
    It properly gives up unused processor cycles, but I don't know if it's entirely accurate when it comes to timing. Does anybody know any functions that I could use that are both accurate and aren't greedy for processor cycles?
    You say "Impressive!", but I already know it
    I'm a hardcore player and I'm not afraid to show it

  2. #2
    Call me AirBronto
    Join Date
    Sep 2004
    Location
    Indianapolis, Indiana
    Posts
    195
    well for one thing you need to be gathering time inside that loop

  3. #3
    Counter-Strike Master
    Join Date
    Dec 2002
    Posts
    38
    gathering time? im not sure what you mean
    You say "Impressive!", but I already know it
    I'm a hardcore player and I'm not afraid to show it

  4. #4
    vae victus! skorman00's Avatar
    Join Date
    Nov 2003
    Posts
    594
    I think loopshot is saying that you may have in infinite loop ther. If curr_time - start_time < 33 from the get go, it will always be that way.

    I would recommend using Vsync. That synchronizes the draw calls with the refresh rate of your card. That's a hardware setting you can turn on, so I think it will work no matter what API you're using.

    Sleep wouldn't be a wise choice unless you calculate how long you should sleep. If you just throw 33 in there, you're going to Sleep that long, even if you're framerate is 1.


    And an after thought...using 100% of the cpu cycles isn't necissarily a bad thing. If you're processor is actually having heating problems because of that, you may have it overclocked when you shouldn't, or don't have decent air flow in your machine.

  5. #5
    Counter-Strike Master
    Join Date
    Dec 2002
    Posts
    38
    i meant that as pseudocode, not actual examples of working code. in place of curr_time it should be GetTickCount(), since GetTickCount gets the current time, lol.

    same thing with Sleep(). i used something similar to the while loop in place of 33 to determine the interval of time to wait.

    ive tried using the DDraw7 method WaitForVerticalBlank(), but it also used up 100% of the processor cycles. then again, i think i was also using it with the while loop i noted previously, so ill have to try it again. ive revised my timing functions last night and the changes seem to be getting me around a steady 30fps, but im still concerned about the precision of those functions. ill do some experimenting with WaitForVerticalBlank to see if that works

    edit: WaitForVerticalBlank gets me a nice, synchronized 60fps (in unison with my monitor), but it has the same problem as the other functions: it makes the program hog all of my processor cycles for itself while it waits.

    i also have another question to ask: should i flip buffers before or after i Sleep(33)? my previous logic had it flip immediately after my logic and then wait before drawing the next frame, but then i realized that i should probably wait, then flip, so the frames are displayed more evenly. which is the proper method that you would recommend?
    Last edited by Bigbio2002; 01-23-2006 at 10:52 PM.
    You say "Impressive!", but I already know it
    I'm a hardcore player and I'm not afraid to show it

  6. #6

    Join Date
    May 2005
    Posts
    1,042
    i also have another question to ask: should i flip buffers before or after i Sleep(33)? my previous logic had it flip immediately after my logic and then wait before drawing the next frame, but then i realized that i should probably wait, then flip, so the frames are displayed more evenly. which is the proper method that you would recommend?
    I use OpenGL, and I do this as soon as I am done rendering the scene


    As for the original problem, I never actually coded this before, but decided to give it a whack and it seems to work (point being if there's something wrong give me a break).

    Anyway
    >>curr_time - start_time

    I am guessing that these are just milliseconds. start_time doesn't make sense, I keep track of the time since the last frame render. Everytime I render a new frame, I update the last time it was rendered.


    this is what I just got working. Note that I have to sync. the graphics with the physics renderer (because if you render physics frames faster than the graphics frames then you end up just seeing the same physics frames more than once, objects 'jiggle'), and everything else is synchronized with the graphics.


    Code:
    //gpFPS is my main graphics timer
    void	MainGameCycle()
    {
    		float	currenttime = gpFPS->FPS_GETTIME(); //gets the time since the start of the program
    		
    		
    		//last time we did a physics frame was also the last time we did a graphics frame
    		float	dt = currenttime - gpFPS->LastTimeBufferSwapped;
    		
    		if(dt	>=	gpPhysicsManager->mSecondsPerFrame)	//this works		
    		{
    			//render graphics, accept input
    		}
    		else 
    		{
    			
    			float	next_frame_time	=	gpFPS->LastTimeBufferSwapped + gpPhysicsManager->mSecondsPerFrame;
    			float	sleep_seconds	=	(next_frame_time - currenttime) * .9;
    			float	sleep_ms		=	SECONDS_TO_MS(sleep_seconds);
    			Sleep((DWORD)sleep_ms);
    			
    		}
    }
    So, I know that I am rendering at a fixed framerate, stored in gpPhysicsManager->mFPS...the inverse of that, is the number of seconds per frame (gpPhysicsManager->mSecondsPerFrame). I can figure out the time that the next frame should come at, and the amount of time, in seconds, to sleep until we get there, and I just convert that to milliseconds.

    Note that I multiplied sleep_seconds by .9 because I don't trust all of the converting going on here, and it's better to sleep less than it is to sleep more.
    I'm not immature, I'm refined in the opposite direction.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Where are fork and wait?
    By xErath in forum C Programming
    Replies: 5
    Last Post: 11-21-2004, 12:43 AM
  2. Passing pointers between functions
    By heygirls_uk in forum C Programming
    Replies: 5
    Last Post: 01-09-2004, 06:58 PM
  3. Embedded functions...
    By dead_cell in forum C++ Programming
    Replies: 3
    Last Post: 06-30-2002, 08:18 PM
  4. API "Clean Up" Functions & delete Pointers :: Winsock
    By kuphryn in forum Windows Programming
    Replies: 2
    Last Post: 05-10-2002, 06:53 PM
  5. Variables do not equal functions!!!
    By me@burk. in forum C Programming
    Replies: 3
    Last Post: 03-23-2002, 06:24 AM