7

I would like to calculate the FPS of the last 2-4 seconds of a game. What would be the best way to do this?

Thanks.

Edit: To be more specific, I only have access to a timer with one second increments.

  • 1
    I think first you have to supply some info (code) regarding the architecture of your game.. – William Jan 14 '11 at 02:29
  • Not much as far as the architecture goes. I can increment a counter every time through the main loop, and I have access to a second timer. –  Jan 14 '11 at 02:37
  • What are you trying to solve? I don't mean to sound coy, but from the esoteric meaning of your question, it seems that you're perhaps going about the wrong way to solve whatever you're trying to solve. – David Titarenco Jan 14 '11 at 02:38
  • I'm not really trying to solve anything. Just looking for the best way to calculate a moving FPS. –  Jan 14 '11 at 02:39
  • I don't understand how you don't have access to a more accurate timer. Depending on the game (or how fast or slow the game is), you won't get anything reasonably close to an accurate FPS if you are only dealing with 1 second precision. – Mark Jan 14 '11 at 19:38
  • @Mark Of course it can be accurate. FPS = Frames Per `Second`. So I can still count the number of frames in each second. That is what FPS means. –  Jan 14 '11 at 20:37

4 Answers4

16

Near miss of a very recent posting. See my response there on using exponential weighted moving averages.

C++: Counting total frames in a game

Here's sample code.

Initially:

avgFps = 1.0; // Initial value should be an estimate, but doesn't matter much.

Every second (assuming the total number of frames in the last second is in framesThisSecond):

// Choose alpha depending on how fast or slow you want old averages to decay.
// 0.9 is usually a good choice.
avgFps = alpha * avgFps + (1.0 - alpha) * framesThisSecond;
Community
  • 1
  • 1
EmeryBerger
  • 3,897
  • 18
  • 29
  • I'm looking for some specific code, I'm just not sure the best way to do it. –  Jan 14 '11 at 02:54
  • hmm, seems to make sense. if you add this code to the answer I might accept it. –  Jan 14 '11 at 03:39
  • This one is nice, using alpha for the moving average. Something in the main loop like: framesThisSecond++;secnow=getseconds();if(secnow!=seclast){doJaysCode;framesThisSecond=0};seclast=secnow; to recalculate each time the seconds look like they changed. – david van brink Jan 14 '11 at 15:12
2

Here's a solution that might work for you. I'll write this in pseudo/C, but you can adapt the idea to your game engine.

const int trackedTime = 3000; // 3 seconds
int frameStartTime; // in milliseconds
int queueAggregate = 0;
queue<int> frameLengths;

void onFrameStart()
{
    frameStartTime = getCurrentTime();
}

void onFrameEnd()
{
    int frameLength = getCurrentTime() - frameStartTime;

    frameLengths.enqueue(frameLength);
    queueAggregate += frameLength;

    while (queueAggregate > trackedTime)
    {
        int oldFrame = frameLengths.dequeue();
        queueAggregate -= oldFrame;
    }

    setAverageFps(frameLength.count() / 3); // 3 seconds
}
Adam Maras
  • 26,269
  • 6
  • 65
  • 91
  • I don't have a precise timer, just a second timer. Sorry I wasn't more clear in the OP. –  Jan 14 '11 at 02:40
1

Could keep a circular buffer of the frame time for the last 100 frames, and average them? That'll be "FPS for the last 100 frames". (Or, rather, 99, since you won't diff the newest time and the oldest.)

Call some accurate system time, milliseconds or better.

david van brink
  • 3,604
  • 1
  • 22
  • 17
  • I don't have access to a precise timer. A second timer is all I am using. –  Jan 14 '11 at 02:38
  • You don't need a timer for this. Just the time. Those are two different things. E.g. many systems can provide millisecond timers, but nanosecond time. – MSalters Jan 14 '11 at 09:34
  • @MSalters Sorry I wasn't clearer, I meant time = timer, timer = time. –  Jan 14 '11 at 20:39
0

What you actually want is something like this (in your mainLoop):

frames++;
if(time<secondsTimer()){
  time = secondsTimer();
  printf("Average FPS from the last 2 seconds: %d",(frames+lastFrames)/2);
  lastFrames = frames;
  frames = 0;
}

If you know, how to deal with structures/arrays it should be easy for you to extend this example to i.e. 4 seconds instead of 2. But if you want more detailed help, you should really mention WHY you haven't access to an precise timer (which architecture, language) - otherwise everything is like guessing...

Constantin
  • 8,721
  • 13
  • 75
  • 126
  • it doesn't really matter why I'm not using an accurate timer, but if you want to know, it is because I am writing portable code at this time. I'm using Linux, and a library I am using does have access to precise time, but, like I said, I want to keep my code portable at this time. –  Jan 14 '11 at 04:26