Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Fps counter results differ from SetFrameLimit() value  (Read 8104 times)

0 Members and 1 Guest are viewing this topic.

Robin

  • Newbie
  • *
  • Posts: 29
  • I have no idea what I'm doing
    • View Profile
    • Crystalshire
Fps counter results differ from SetFrameLimit() value
« on: October 29, 2014, 04:16:55 pm »
So I wrote a simple FPS counter class which literally counts how many times it is updated per second. Seems to work fine, however when using the RenderWindow.SetFramerateLimit() method the counter gives a different count to what I'm limiting to.

RenderWindow.SetFramerateLimit(16) returns a count of 17.
RenderWindow.SetFramerateLimit(30) returns a count of 32.
RenderWindow.SetFramerateLimit(60) returns a count of 64.
RenderWindow.SetFramerateLimit(120) returns a count of 144.

Is this expected behaviour or is my counter just horribly written?

public class FpsCounter
{
        private uint _timer;
        private int _frameCount;
        private int _fps;

        public int Fps
        {
                get
                {
                        return _fps;
                }
        }

        public void Update()
        {
                if (_timer < Time.TickCount)
                {
                        _fps = _frameCount;
                        _frameCount = 0;
                        _timer = Time.TickCount + 1000;
                }

                _frameCount++;
        }
}
 

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

Robin

  • Newbie
  • *
  • Posts: 29
  • I have no idea what I'm doing
    • View Profile
    • Crystalshire

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: Fps counter results differ from SetFrameLimit() value
« Reply #3 on: October 29, 2014, 05:05:29 pm »
One follow-up question I had about that FAQ.

Quote
In recent revisions of SFML, the timer resolution is temporarily increased during a call to sf::sleep to increase the likelihood of your sf::sleep call sleeping for the correct amount of time.

Is this in any way similar to Google Chrome's timer resolution "bug" that caused a weird sort of internet mini-scandal when people noticed it was shortening their battery life?

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: Fps counter results differ from SetFrameLimit() value
« Reply #4 on: October 29, 2014, 06:01:33 pm »
The thing that enraged people about that Chrome "bug" is that it was forcing a higher timer resolution even when it wasn't necessary. Obviously when you are just reading an article on Wikipedia or similar as opposed to watching a video, you really don't profit from a higher timer resolution, but the developers of Chrome thought it was a good idea to keep the timer at a high resolution no matter what the browser is doing.

Obviously, since SFML is a Multimedia library, it makes sense for it to increase the timer resolution, and it only does so if you use sf::sleep or any of its relatives. If you want to save battery life, close the SFML application, it's as simple as that. People who expect a GPU accelerated application to run power efficiently can go look for another multimedia library that manages to pull it off, and if you ask me, they will be looking for a really long time ;).
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
Re: Fps counter results differ from SetFrameLimit() value
« Reply #5 on: October 30, 2014, 01:52:26 pm »
Not to mention that using TickCount is very inaccurate at high speeds. You should instead use the SFML Clock and Time classes.
Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor

Robin

  • Newbie
  • *
  • Posts: 29
  • I have no idea what I'm doing
    • View Profile
    • Crystalshire
Re: Fps counter results differ from SetFrameLimit() value
« Reply #6 on: October 30, 2014, 05:12:24 pm »
Not to mention that using TickCount is very inaccurate at high speeds. You should instead use the SFML Clock and Time classes.

The system module was never part of the SFML .NET framework AFAIK. It's certainly not in the version I'm using.

Also, how is TickCount inaccurate at high speeds? In this implementation it's simply checking for when 1,000 milliseconds have passed so it can display the amount of frames rendered in that time. What benefit would the SFML Clock and Time classes provide over this?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Fps counter results differ from SetFrameLimit() value
« Reply #7 on: October 30, 2014, 05:46:34 pm »
Quote
The system module was never part of the SFML .NET framework AFAIK. It's certainly not in the version I'm using.
It was added after 2.1.
Laurent Gomila - SFML developer

Robin

  • Newbie
  • *
  • Posts: 29
  • I have no idea what I'm doing
    • View Profile
    • Crystalshire
Re: Fps counter results differ from SetFrameLimit() value
« Reply #8 on: October 30, 2014, 05:49:28 pm »
Quote
The system module was never part of the SFML .NET framework AFAIK. It's certainly not in the version I'm using.
It was added after 2.1.

Huh. Was there a specific reason you decided to implement it now?

I'll take a look in to upgrading my version.

Also can you elaborate on what zsbzsb said about the accuracy compared to TickCount in high performance scenarios?

zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
Re: Fps counter results differ from SetFrameLimit() value
« Reply #9 on: October 30, 2014, 06:40:22 pm »
I have written posts on it before. In short, the only way to guarantee a high resolution timer on windows at least is by using the QueryPerformanceCounter function in the Win32 API. The only way to get access to it in the CLI framework is by using the System.Diagnostics.Stopwatch class. The class provides either Ticks or a Timespan property. However if you want the high resolution you must provide the conversion yourself from Ticks to whatever representation you want. Timespan has a limited resolution whereas using Ticks will give you the best available precision.

Now when we are only getting as precise as milliseconds you can quickly loose precision. Consider that at 60 FPS every frame consumes 16.66...7 milliseconds. But with the standard classes there is no way to handle milliseconds with floats. So it will end up rounding the difference off. You will either end up gaining or loosing time. Either way, SFML classes handle time using microseconds so you will end up with a much higher precision. I have looked into it a great deal and the best solution is always a high resolution clock. That is why my NetEXT library for quite a while implemented SFML style Time and Clock classes until they made their way into the master.

If you want I can dig up more links, but I think the following for now is quite sufficient to show some of the precision problems.

http://geekswithblogs.net/BlackRabbitCoder/archive/2012/01/12/c.net-little-pitfalls-stopwatch-ticks-are-not-timespan-ticks.aspx
« Last Edit: October 30, 2014, 06:52:16 pm by zsbzsb »
Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Fps counter results differ from SetFrameLimit() value
« Reply #10 on: October 30, 2014, 06:45:00 pm »
Quote
Huh. Was there a specific reason you decided to implement it now?
The .Net framework provides equivalent functionality, so it was not strictly needed. However we decided that it would still be a valuable addition (and it makes some other things a little cleaner).

Quote
Also can you elaborate on what zsbzsb said about the accuracy compared to TickCount in high performance scenarios?
I think he was talking about the bad resolution of this timer, which is tied to the OS scheduler (~16 ms by default). But if you measure 1 whole second, I don't think it makes such a difference, it's just a 1.6% error maximum.
Laurent Gomila - SFML developer

zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
Re: Fps counter results differ from SetFrameLimit() value
« Reply #11 on: October 30, 2014, 06:56:00 pm »
Quote
The .Net framework provides equivalent functionality

Not exactly, and as you said it is much cleaner than writing Stopwatch.Ticks / 1000 or whatever it takes.

Quote
which is tied to the OS scheduler (~16 ms by default

Depends on which built in method you are using and how it is implemented.

Quote
I don't think it makes such a difference, it's just a 1.6% error maximum.

We aren't talking exactly about the just measuring FPS, measuring elapsed time in general for consistent game updates is very important and the difference will add up.
Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor