SFML community forums

Help => General => Topic started by: smguyk on March 02, 2014, 03:49:11 pm

Title: Simple program high CPU usage
Post by: smguyk on March 02, 2014, 03:49:11 pm
I'm currently working on a platformer and trying to implement a timestep, but for framerate limits greater than 60 the CPU usage goes up from 1% to 25% and more.

I made this minimal program to demonstrate the issue. There are two comments (in red, lines 10-13, lines 26-30) in the code that describe the problem and what I have tested.

Note that the FPS stuff is not relevant to the problem (I think).

I tried to keep the code short and simple:

    #include <memory>
    #include <sstream>
    #include <iomanip>
    #include <SFML\Graphics.hpp>
   
    int main() {
      // Window
      std::shared_ptr<sf::RenderWindow> window;
      window = std::make_shared<sf::RenderWindow>(sf::VideoMode(640, 480, 32), "Test", sf::Style::Close);
      /*
      When I use the setFramerateLimit() function below, the CPU usage is only 1% instead of 25%+
      (And only if I set the limit to 60 or less. For example 120 increases CPU usage to 25%+ again.)
      */

      //window->setFramerateLimit(60);
   
      // FPS text
      sf::Font font;
      font.loadFromFile("font.ttf");
      sf::Text fpsText("", font, 30);
      fpsText.setColor(sf::Color(0, 0, 0));
   
      // FPS
      float fps;
      sf::Clock fpsTimer;
      sf::Time fpsElapsedTime;
      /*
      When I set framerateLimit to 60 (or anything less than 60)
      instead of 120, CPU usage goes down to 1%.
      When the limit is greater, in this case 120, CPU usage is 25%+
      */

      unsigned int framerateLimit = 120;
      sf::Time fpsStep = sf::milliseconds(1000 / framerateLimit);
      sf::Time fpsSleep;
      fpsTimer.restart();
   
      while (window->isOpen()) {
        // Update timer
        fpsElapsedTime = fpsTimer.restart();
        fps = 1000.0f / fpsElapsedTime.asMilliseconds();
   
        // Update FPS text
        std::stringstream ss;
        ss << "FPS: " << std::fixed << std::setprecision(0) << fps;
        fpsText.setString(ss.str());
   
        // Get events
        sf::Event evt;
        while (window->pollEvent(evt)) {
          switch (evt.type) {
          case sf::Event::Closed:
            window->close();
            break;
          default:
            break;
          }
        }
   
        // Draw
        window->clear(sf::Color(255, 255, 255));
        window->draw(fpsText);
        window->display();
   
        // Sleep
        fpsSleep = fpsStep - fpsTimer.getElapsedTime();
        if (fpsSleep.asMilliseconds() > 0) {
          sf::sleep(fpsSleep);
        }
   
      }
   
      return 0;
    }

I don't want to use SFML's setFramerateLimit(), but my own implementation with the sleep because I will use the fps data to update my physics and stuff.

Is there a logic error in my code? I fail to see it, given it works with a framerate limit of for example 60 (or less). Is it because I have a 60 Hz monitor?

PS: Using SFML's window->setVerticalSync() doesn't change the results

Thank you
Title: Re: Simple program high CPU usage
Post by: The Terminator on March 02, 2014, 03:56:48 pm
Have a look at this article:

http://gafferongames.com/game-physics/fix-your-timestep/
Title: Re: Simple program high CPU usage
Post by: zsbzsb on March 02, 2014, 03:59:06 pm
Prefer vertical sync over sleep based framerate limits. And don't reinvent the wheel, just use setFramerateLimit(...) if you don't want for vsync.

As for getting the delta time, just use a clock and measure time elapsed between frames - there is no need to complicate your code like you are doing.

Oh and don't mix vsync and setFramerateLimit(...)  ;)

Have a look at this article:

Please don't just post links to articles without explaining - for starters the OP isn't even asking about timesteps, but rather how to limit the framerate and measure time.
Title: Re: Simple program high CPU usage
Post by: Hapax on March 02, 2014, 04:02:46 pm
I don't understand why you refuse to use setFrameLimit(). You can still do many loops of physics etc. per frame depending on the time passed (you should read the article just linked (http://gafferongames.com/game-physics/fix-your-timestep/) to by The Terminator)

That said, I run your code as is (framerateLimit = 120) and CPU didn't notice anything.

Edit: I slightly apologise for the CPU point. I often forget that my CPU is awesome  8)
Title: Re: Simple program high CPU usage
Post by: smguyk on March 02, 2014, 04:44:55 pm
Thank you for all the input, I will have to think about it for a while. I may toss my approach and implement the last solution from the article.

(PS: I have actually read the article earlier, but wanted to do something different.)