C ++: counting all frames in a game

Not a very good title, but I did not know what to call it.

In any case, I count the total frames (so I can calculate the average FPS) in my game with long int . Just in case, when the game lasted a long time, what should I do to make sure that my long int does not increase to the limit? And what happens if it passes through its limit?

Thanks.

+3
source share
6 answers

The average FPS throughout the game is not a very useful statistic. Typically, you will want to measure peaks and valleys, such as maximum fps / low fps and the number of frames spent below thresholds.

In fact, I would not worry. Even if you just need to use the 32-bit unsigned int, your game can run at 60 frames per second for 19884 hours before it overflows. You must be fine.

EDIT:

The best way to detect overflow in this case is to check and see if the integer decreases after the value. If this is the case, you can simply leave another counter around which there will be a number of times crowded by you.

+4
source

This problem is present for any counters.

For your specific problem, I would not bother.

A long int counts up to 2 billion (or more) in the worst cases (on 32-bit computers / consoles). Suppose that your game does 1000 frames per second (that's a lot!). It takes 20,000,000 seconds to fill up the counter: more than 5,000 hours, more than 231 days.

I'm sure something else will stop your game if you try to run it for so long!

+8
source

Instead, I would prefer to use e x a constant-weighted moving average . This approach will kill two birds with one stone: this will avoid the problem of accumulating a large amount, and will also adapt to recent behavior, so that the accumulated average of 100 feet in 2010 will not distort the average so that the 2fps speed seems acceptable for a month or so in 2011 :).

+5
source

You can actively check overflow in your arithmetic operations. E. g. SafeInt can do this for you. Of course, performance is worse than for i++ .

However, it is unlikely that a 32-bit integer will overflow if you always increment by one.

+1
source

If long int is 32-bit, the maximum value is 2 ^ 31-1, so when updating 1 ms it will overflow after 24.9 days, and not 231 [2 ^ 31/1000/60/60/24].

I hope that not too OT ... in general for games this may not be a problem, but for other applications. The common mistake to be careful is something like

 extern volatile uint32_t counter; uint32_t one_second_elapsed = counter + 1000; while ( counter < one_second_elapsed ) do_something(); 

If the counter + 1000 overflows, then do_something () will not be called. A way to check it out

 uint32_t start = counter; while ( counter - start < 1000 ) do_something(); 
+1
source

It is probably best to use the average for a small number of frames. You mentioned that you want to calculate the average value, but there really is no reason to keep so many samples around to calculate the average value. Just keep the current number of frames for a short period of time (where small can be between 10-50 frames - we usually use 16). You can then use this sum to calculate average frames per second. This method also helps smooth out frame time reports so that numbers don't skip everywhere. One thing to keep in mind is that if you average too much time, then the framerate bursts become more β€œhidden”, which means that it can be more difficult to identify frames that cause a drop in frame rate if these frames only happen so often.

Something like this would be sufficient, I think (without checking the code):

 // setup some variables once const int Max_samples = 16; // keep at most 16 frametime samples int FPS_Samples = 0; int Current_sample = 0; int Total_frametime = 0.0f; float Frametimes[Max_samples]; for ( int i = 0; i < Max_samples; i++ ) { Frametimes[i] = 0.0f; 

Then, when you calculate your cycle time, you can do something like this:

 // current_frametime is the new frame time for this frame Total_frametime -= Frametimes[Current_sample]; Total_frametime += current_frametime; Frametimes[Current_sample] = current_frametime; Current_sample = ( Current_sample + 1 ) % Max_samples; // move to next element in array Frames_per_second = Max_samples / Total_frametime; 

This is a gross reduction and probably can use some error checking, but it gives a general idea.

0
source

Source: https://habr.com/ru/post/1335522/


All Articles