tags:

views:

1000

answers:

3

I wrote a component to display current FPS.
The most important part of it is:

    public override void Update(GameTime gameTime)
    {
        elapseTime += (float)gameTime.ElapsedRealTime.TotalSeconds;
        frameCounter++;

        if (elapseTime > 1)
        {
            FPS = frameCounter;
            frameCounter = 0;
            elapseTime = 0;
        }
        base.Update(gameTime);
    }


    public override void Draw(GameTime gameTime)
    {
        spriteBatch.Begin();

        spriteBatch.DrawString(font, "FPS " + ((int)FPS).ToString(), position, color, 0, origin, scale, SpriteEffects.None, 0);

        spriteBatch.End();

        base.Draw(gameTime);
    }

In most cases it works ok, but recently I had a problem.
When I put following code into Update method of game strange thing starts to happen.

       if (threadPath == null || threadPath.ThreadState != ThreadState.Running)
        {
            ThreadStart ts = new ThreadStart(current.PathFinder.FindPaths);
            threadPath = new Thread(ts);
            threadPath.Priority = ThreadPriority.Highest;
            threadPath.Start();
        }

Main idea of this code is to run pathFinding algorithm in different thread all the time.

By strange things I mean that sometimes FPS drasticly decreases, this is obvious, but displayed FPS changes more often than once a second. If I understand this code FPS can't change more often than once a second.

Can someone explain me what's going on?

Edit 26.03.2010
I've posted also code of Draw method.

Edit 31.03.2010 Answers to Venesectrix questions
1) are you running with a fixed or variable time step?
IsFixedTimeStep and SynchronizeWithVerticalRetrace is set to true.
2)Were you moving the XNA window around when this occurred?
No
3)Did the XNA window have focus?
Yes
4) How noticeable was it (ie, updating so fast you can't read it, or just barely updating more than a second)?
I was able to read updates, FPS was updating ~3 times a second.
5) And all of this only happens with the thread code in there?
Yes

+7  A: 

Shawn Hargreaves has a great post about this here. The first difference I see between his code and yours is the fact that you reset your elapseTime to 0 each time, which will lose some time, whereas Shawn just subtracts 1 second from his elapsedTime. Also, Shawn uses ElapsedGameTime instead of ElapsedRealTime. He updates his frameCounter in the Draw function instead of the Update function as well.

As far as why he uses ElapsedRealTime, he explains it in a comment after the post:

> Surely 1 / gameTime.ElapsedRealTime.TotalSeconds

> will therefore give the current framerate.

That will tell you how long it was since the previous call to Update, but that is not the same thing as your framerate!

a) If the game is dropping frames, Update will be called more frequently in order to catch up. You want to time the number of actual draws that are taking place, not just these extra catch-up logic frames.

b) The time for a single Update can fluctuate widely, so the figure you get out of that will be too flickery to be easily readable.

I would try his component, and see if it works for you. The post is pretty old, and I think you will have to change LoadGraphicsContent to LoadContent and UnloadGraphicsContent to UnloadContent, as another one of the comments points out.

Venesectrix
@Venesectrix: Thanks, changing from ElapsedRealTime to ElapsedGameTime solved this problem, but the question why displayed FPS was changing more often than once a second is still open.
Tomek Tarczynski
Can you post the code for your draw function as well?
Venesectrix
I post it, but there is nothing interesting.
Tomek Tarczynski
So are you still seeing the FPS change more than once when you use ElapsedGameTime? Are you running this on Windows or Xbox?
Venesectrix
ElapsedGameTime solved this problem, but the question is what the hell does ElapsedRealTime returns? I'm just curious about it.I run this on Windows.
Tomek Tarczynski
Couple more questions for you: are you running with a fixed or variable time step? Were you moving the XNA window around when this occurred? Did the XNA window have focus? How noticeable was it (ie, updating so fast you can't read it, or just barely updating more than a second)? And all of this only happens with the thread code in there?
Venesectrix
+1  A: 

As an aside ... you should avoid setting the thread priority. By assigning the highest thread priority to what should be a background thread, you could end up starving the main thread of cpu time because the scheduler would give priority to threadPath

Joel Martinez
@Joel Martinez : In normal version this thread won't have highest priority. I was just checking how much would my FPS decrease if I change priority.
Tomek Tarczynski
A: 

Are you actively checking if IsRunningSlowly is being changed? Even with IsFixedTimeStep to true, if your program isn't able to do as many Updates as it expects, it will call it more frequently.

A way I have mitigated this before is by directly calling ResetElapsedTime() instead of keeping track of it yourself.

Not sure if that'll work for you though. I did notice that when i was debugging the previous issue I had, it wouldn't call the extra Updates, probably a 'feature' when debugging.

Jason M