Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I've searched around here and Google and at last I looked at Fix your Timestep! article on the web which most of the people suggest. In according to that article I came up with an update method like this, but I still have problems. Whenever I instantiate more and more objects in my scene, I'll get much slower physical interactions. I've fixed other sub-systems that they were wasting cycles during update process and now I've tracked my physics performance drop to this point. I think the way I'm updating my physics is somehow wrong because I'm using a fixed timing of 1.0 / 60.0 for my Box2D engine. Can someone help and point out my mistakes in my update process?

void Core::Update()
{
        // Input
        this->cInput->Update();

        // Physics
        this->cPhysics->Update();

        // Keep frame rate
        static const double desiredTime = 1.0 / 60.0;
        static double currentTime = (double)time(NULL);
        static double accumulator = 0.0;

        double newTime = (double)time(NULL);
        double frameTime = newTime - currentTime;
        if(frameTime > 0.25){ frameTime = 0.25; }
        currentTime = newTime;

        accumulator += frameTime;

        while(accumulator >= desiredTime)
        {
            accumulator -= desiredTime;
        }

        // Render
        this->cRender->Update();
}

I've read that you shouldn't tie your physics frame rate with render frame rate and that's why I've put this->cPhysics->Update(); above.

Edit

My new update method is something like this:

    // Keep frame rate
static const double desiredTime = 1.0 / 60.0;
static double currentTime = (double)(GetTickCount());
    static double accumulator = 0.0;

    double newTime = (double)(GetTickCount());
    double frameTime = newTime - currentTime;

    if(frameTime > 0.25){ frameTime = 0.25; }
    currentTime = newTime;

    accumulator += frameTime;

    while(accumulator >= desiredTime)
    {
        // Input
        this->cInput->Update();

        // Physics
        this->cPhysics->Update(desiredTime);

        // Scripts
        this->cScripts->Update();

        accumulator -= desiredTime;
    }

Actually I've used my previous approach, but with a slight change. I'm not sure what I'm doing is right but it solved my performance issue. First I changed currentTime to get time in milliseconds instead of seconds. At the end, I've moved all of my update codes except render's update to time step loop. Would someone tell me if this is correct?

share|improve this question
1  
    
@VaughanHilts that's the article that I've already checked. –  MahanGM Aug 3 '13 at 18:04
    
This psuedo code makes no sense, and I feel you don't understand the purpose of the Fix Your Timestep article. The whole point of the Fix Your Timestep article is to allow a physics library to step at a frequency differently from which you render. This is a nice thing to have, but not required. Here's another resource for timestepping + interpolation: gamedev.tutsplus.com/tutorials/implementation/… Of course you'll have a bottleneck here, you're doing your entire engine loop here. For optimization you'll need more specific info. –  RandyGaul Aug 3 '13 at 19:40
    
@RandyGaul I'm impressed with your article. This is part of an actual code that I'm using and Core::Update is called by a higher level loop which is the game loop, anyway, I can't understand why you're saying you're doing your entire engine loop here because I have no idea how else I can do this! And I've profiled most of other parts and I know my physics update rate is the problem. I'll check your article. –  MahanGM Aug 3 '13 at 23:45
    
@MahanGM Well I mean, the bottleneck must be here because you're doing so much in this loop. So if you wanted to analyze performance (assuming your timestepping code was corrected), you would need to know more about the specifics of the code called within the timestepping loop. If you need more help you can always just respond here and I'll take a look. –  RandyGaul Aug 4 '13 at 0:28

1 Answer 1

The problem lies here

    static double currentTime = (double)time(NULL);
    static double accumulator = 0.0;

    double newTime = (double)time(NULL);

your currentTime and newTime are roughtly the same that way, this can't work.

you need to measure the time you needed for one frame (the last frame) and sleep the remaining time till you hit your 1.0s/60s mark. Don't forget that the sleeping doesn't sleep exactly the amount of time you passed in so you need to compesate for that.

An optional way to get the used time for the frames is to use a sliding window approach for all frame times and sum the times and divide by the count.

Another important oint is to limit your delta-time you actually measured (say to 0.2 seconds) for avoiding instabilities.

Edit 1 Example code to illustrate it

private double Time = 0.0;

private double deltaTArray[10];
private unsigned int deltaTArrayI;

// NOTE< this->currentTime must be set once before this is called >


void Core::Update()
{
    // Input
    this->cInput->Update();

    double newTime = (double)time(NULL);

    double deltaT = newTime - this->currentTime;

    this->currentTime = newTime;

    deltaT = min(deltaT, 0.25); // because of stability

    this->deltaTArray[this->deltaTArrayI] = deltaT;

    (this->deltaTArrayI)++;
    this->deltaTArrayI = this->deltaTArrayI % 10;

    // calculate delta T as average of the sliding window
    double deltaTAverage = 0.0;

    for( unsigned int i = 0; i < 10; ++i )
    {
        deltaTAverage += this->deltaTArray[i];
    }

    deltaTAverage = deltaTAverage / (double)10;

    // Physics
    this->cPhysics->Update(deltaTAverage);

    // Keep frame rate
    sleep(max((1.0/60.0)-deltaTAverage, 0));

    // Render
    this->cRender->Update();
}
share|improve this answer
    
Can you give me a coding example? –  MahanGM Aug 3 '13 at 18:06
    
According to this article altdevblogaday.com/2012/06/05/in-praise-of-idleness, do I really have to use Sleep()? –  MahanGM Aug 3 '13 at 18:30
    
@MahanGM the article has nothing to do with it because it is about syncronisation/waiting of multiple threads, i don't do such a thing, it is perfectly fine. Sleep doesn't do busy waiting. –  Quonux Aug 3 '13 at 18:36
    
Thank you for your time. I tested your code and it seems I still got my problem. Actually my problem is with the physics frame rate. If I set it to 1.0 / 30.0 it'll run two times faster and the amount of objects that I should create to test my performance would become two times larger. This means the timing of my physics engine has a direct relation on my issue. –  MahanGM Aug 3 '13 at 18:42
    
do you want to use a fixed timestep or a dynamic for your physics engine, i updated my code for the dynamic timestep –  Quonux Aug 3 '13 at 19:28

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.