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

Author Topic: Simple program high CPU usage  (Read 2609 times)

0 Members and 1 Guest are viewing this topic.

smguyk

  • Jr. Member
  • **
  • Posts: 79
    • View Profile
Simple program high CPU usage
« 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

The Terminator

  • Full Member
  • ***
  • Posts: 224
  • Windows and Mac C++ Developer
    • View Profile
Re: Simple program high CPU usage
« Reply #1 on: March 02, 2014, 03:56:48 pm »
Current Projects:
Technoport

zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
Re: Simple program high CPU usage
« Reply #2 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.
« Last Edit: March 02, 2014, 04:02:51 pm by zsbzsb »
Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Simple program high CPU usage
« Reply #3 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 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)
« Last Edit: March 02, 2014, 04:05:25 pm by Golden Eagle »
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

smguyk

  • Jr. Member
  • **
  • Posts: 79
    • View Profile
Re: Simple program high CPU usage
« Reply #4 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.)