简单的C++SFML程序高CPU使用率



我目前正在开发一个平台生成器,并试图实现一个时间步长,但对于大于60的帧速率限制,CPU使用率从1%上升到25%甚至更多。

我制作了这个最小程序来演示这个问题。代码中有两条注释(第10-13行和第26-30行)描述了问题和我测试的内容。

请注意,FPS内容与问题无关(我认为)。

我试着让代码简洁明了:

#include <memory>
#include <sstream>
#include <iomanip>
#include <SFMLGraphics.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;
}

我不想使用SFML的setFramerateLimit(),而是我自己的睡眠实现,因为我会使用fps数据来更新我的物理和其他东西。

我的代码中有逻辑错误吗?我看不到它,因为它的帧速率限制为60(或更低)。是因为我有一个60赫兹的显示器吗?

PS:使用SFML的窗口->setVerticalSync()不会改变的结果

我用这个答案回答了另一个类似的问题。

问题是,它并不能完全帮助你使用CPU,但我尝试了你的代码,它在120 FPS的1%CPU使用率下运行良好(甚至更多)。当你制作一个带有"游戏循环"的游戏或互动媒体时,你不想因为睡觉而失去性能,你想尽可能多地使用电脑给你的cpu时间。不用睡觉,你可以处理其他数据,比如加载东西、寻路算法等,或者只是不限制渲染。

我提供了一些有用的链接和代码,在这里:


类似的问题:没有帧速率限制的移动C++SFML。

你真正需要的是固定的时间步长。看看SFML游戏开发书籍的源代码。以下是Application.cpp:

const sf::Time Game::TimePerFrame = sf::seconds(1.f/60.f);
// ...
sf::Clock clock;
sf::Time timeSinceLastUpdate = sf::Time::Zero;
while (mWindow.isOpen())
{
sf::Time elapsedTime = clock.restart();
timeSinceLastUpdate += elapsedTime;
while (timeSinceLastUpdate > TimePerFrame)
{
timeSinceLastUpdate -= TimePerFrame;
processEvents();
update(TimePerFrame);
}
updateStatistics(elapsedTime);
render();
}

如果这不是您真正想要的,请参阅"修复时间步长!"Laurent Gomila本人在SFML论坛中将其联系起来。

我建议使用setFrameRate限制,因为它是在SFML中本地实现的,工作效果会更好。为了获得经过的时间,你必须做:

fpsElapsedTime = fpsTimer.getElapsedTime();

如果我必须实现类似的东西,我会这样做:

/* in the main loop */
fpsElapsedTime = fpsTimer.getElapsedTime();
if(fpsElapsedTime.asMillisecond() >= (1000/framerateLimit))
{
fpsTimer.restart();
// All your content
}

另外,使用sf::Color::White或sf::Color::Black代替(sf::Color(255255255))

希望这个帮助:)

最新更新