我目前正在开发平台游戏并尝试实现时间步长,但对于大于 60 的帧速率限制,CPU 使用率从 1% 上升到 25% 甚至更多。
我制作了这个最小程序来演示这个问题。代码中有两条注释(第 10-13 行,第 26-30 行)描述了问题以及我测试过的内容。
请注意,FPS 内容与问题无关(我认为)。
我尽量使代码简短:
#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;
}
我不想使用 SFML 的 setFramerateLimit(),而是我自己的 sleep 实现,因为我将使用 fps 数据来更新我的物理和东西。
我的代码有逻辑错误吗?我看不到它,因为它适用于例如 60(或更少)的帧速率限制。是因为我有一个 60 Hz 的显示器吗?
PS:使用 SFML 的 window->setVerticalSync() 不会改变结果
最佳答案
我回答了另一个similar question有了这个answer .
问题是,它并不能完全帮助您降低 CPU 使用率,但我尝试了您的代码,它在 120 FPS(以及更多)的 1% cpu 使用率下运行良好。当您使用“游戏循环”制作游戏或交互式媒体时,您不想因 sleep 而失去性能,您希望使用计算机可以给您的尽可能多的 CPU 时间。您可以处理其他数据,例如加载内容、寻路算法等,而不是休眠,或者只是不限制渲染。
我提供了一些有用的链接和代码,这里是:
Similar question: Movement Without Framerate Limit C++ SFML.
What you really need is fixed time step. Take a look at the SFML Game development book source code. Here's the interesting snippet from
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(); }
If this is not really what you want, see "Fix your timestep!" which Laurent Gomila himself linked in the SFML forum.
关于c++ - 简单的 C++ SFML 程序高 CPU 使用率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22128872/