Skip to main content
GameDev.net gamedev.net
🔒 Locked

How to calculate frames per second?

Started by kerryhall Sep 30, 2008 at 7:44 PM 8 replies 52.3k views
Original Post
kerryhall
kerryhall
Hey all, I am looking for a way to calculate frames per second using just C/C++ time functions. (No GetTickCount!) Thanks!
kerryhall
kerryhall
Perfect! That is exactly what I was looking for. Thanks!
greenhybrid
greenhybrid
as you are new to clock(), just take this as an advice.

the resolution (wrt time) and the actual output of clock() is not defined in the C- or C++-standard, i.e. it can be that the output of clock() only changes 20 times per second (resolution=1/20th of a second), while clock() actually defines 1000 clocks to be a second (so it would go 0,50,100,150,...1050,1100,...).

Some systems also define 1000 clocks per second, at a resolution of 1/1000second (can be configured by the user when compiling a custom linux kernel, e.g.).

So, one safe way is this:
const float start = static_cast <float> (clock ()) / static_cast <float> (CLOCKS_PER_SEC);while (true) {    const float now = (static_cast <float> (clock ()) / static_cast <float> (CLOCKS_PER_SEC)) - start;    cout << now << " seconds    \r";}
MJP
MJP
Typically you'll want to measure the time delta (the amount of time elapsed since the last frame) using some sort of high-resolution timing function. Which one to use usually depends on the platform, you'll want something with *at least* 1ms resolution.

Once you have your time delta, you simply divide 1 by this value to get frame rate for that particular instant in time.

float newTime = SomeTimingFunction();float dt = newTime - oldTime;float fps = 1.0f / dt;oldTime = newTime;


However if you use this fps value directly and just display it to the screen, you'll find it's rather irratic. The amount of time it takes to complete a frame will typically vary a bit from frame to frame, and this will make it hard to read and not so useful. To get around this, you can filter your result a bit taking a bunch of samples and averaging the result.

static const int NUM_FPS_SAMPLES = 64;float fpsSamples[NUM_FPS_SAMPLES]int currentSample = 0;float CalcFPS(int dt){    fpsSamples[currentSample % NUM_FPS_SAMPLES] = 1.0f / dt;    float fps = 0;    for (int i = 0; i < NUM_FPS_SAMPLES; i++)        fps += fpsSamples;    fps /= NUM_FPS_SAMPLES;    return fps;}
oliii
oliii
yup. Another function to get the clock accuracy on windows platform is QueryPerformanceCounter(). That along with QueryPerformanceFrequency() and some integer maths will give you a very accurate time read.

some random post.
Everything is better with Metal.
implicit
implicit
Quote:
Original post by MJP
float newTime = SomeTimingFunction();float dt = newTime - oldTime;float fps = 1.0f / dt;oldTime = newTime;
You'll probably also want to keep the old/new tick values as raw integers until after the subtraction. That way you'll increase the precision and handle timer overflow gracefully.

Quote:
Original post by MJP
static const int NUM_FPS_SAMPLES = 64;float fpsSamples[NUM_FPS_SAMPLES]int currentSample = 0;float CalcFPS(int dt){    fpsSamples[currentSample % NUM_FPS_SAMPLES] = 1.0f / dt;    float fps = 0;    for (int i = 0; i < NUM_FPS_SAMPLES; i++)        fps += fpsSamples;    fps /= NUM_FPS_SAMPLES;    return fps;}
Similarly you could simply store the absolute tick values of each frame in the array here, and subtract the oldest entry from the current tick to get the elapsed time. With increased precision as mentioned above, though that is far less important here, as well as avoiding the loop.

An alternative scheme is to take, say, 90% of the old FPS value and 10% of the new to form the new framerate.
greenhybrid
greenhybrid
and, when still using clock(): it is always good to measure after a second, and after (e.g.) five seconds, to smooth out inaccuracies in the clock()-timer (so you have a fps, and a fp/5s timer on your screen)
frob
frob
There are several numbers that are much more useful than the single frames per second count.


The single most important set of numbers, in my view, is the min/avg/max of milliseconds per frame.

Consider these scenarios. We'll assume a 75 Hz refresh rate monitor, so that's our ideal frame rate.
FPS: 75min/avg/max: 0 / 13 / 999
Sure it is 75 frames per second. But it is really really bad.

This is the extreme example. Even though it gets 75 frames per second, 74 frames take almost zero time and one frame consumes the remainder of the second. That's essentially a slide show of one new image per second. Seeing a slide show while looking only at the average FPS will result in confusion.

FPS: 75min/avg/max: 7 / 13 / 49
This is also 75 frames per second, but it reveals useful information about the program.

The worst frame is running at 49 milliseconds, or roughly 20 Hz. The fastest frame is at 7 ms or 150 Hz. This shows that the work needs to be balanced out between frames, but is good on average, and even the worst case is probably acceptable.


FPS: 75min/avg/max: 13 / 13 / 14
Again we're at 75 frames per second, and it is very good.

With this one you know that you are taking almost exactly the same amount of time for every frame, consistently. It's a solid frame rate.




After that, I feel the second most useful set of numbers is the processing time between frames. Again, this is in the min/avg/max format, but generally it is better to show this number in microseconds. This number is going to fluctuate much more than the displayed framerate, but you are most interested in avoiding spikes. It also gives you an idea of how much additional work you can do every frame.


Finally, it is nice (but not essential) to have a one second average and a 5 second average, both updated every second.

Throw in a bit of coloring on the numbers and render them in the corner. It is a very rough beginning to an in-game profiling system. Later you'll want to add additional counters for processing time of AI, rendering, and everything else. It isn't that hard to do, but that's another post.
Grantax
Grantax
If you just want the framerate, and you'd like it to update every second so it would actually be possible to read, would there be any downside to actually just counting the frames per second?


//Inside render loop++frames;overtime = clock() - nextUpdate;if (overtime > 0){    fps = frames / (float)(1+ (float)overtime/(float)CLOCKS_PER_SEC);    frames = 0;    nextUpdate = clock() + 1 * CLOCKS_PER_SEC;}

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.