C++ 限制循环c和x2B中的fps+;
我有一个简单的fps限制器,它可以工作:C++ 限制循环c和x2B中的fps+;,c++,sleep,frame-rate,chrono,C++,Sleep,Frame Rate,Chrono,我有一个简单的fps限制器,它可以工作: 时钟 #包括 使用名称空间std::chrono; 上课钟 { 高分辨率时钟:时间点开始时间; 公众: 时钟(); 持续时间重新启动(); }; Clock.cpp #include "Clock.h" Clock::Clock() : startTime(high_resolution_clock::now()) { } duration<double> Clock::restart() { high
时钟
#包括
使用名称空间std::chrono;
上课钟
{
高分辨率时钟:时间点开始时间;
公众:
时钟();
持续时间重新启动();
};
Clock.cpp
#include "Clock.h"
Clock::Clock()
: startTime(high_resolution_clock::now())
{
}
duration<double> Clock::restart()
{
high_resolution_clock::time_point now = high_resolution_clock::now();
duration<double> elapsed = now - startTime;
startTime = now;
return elapsed;
}
#包括“Clock.h”
时钟::时钟()
:开始时间(高分辨率时钟::现在()
{
}
持续时间时钟::重新启动()
{
高分辨率时钟::现在的时间点=高分辨率时钟::现在();
持续时间=现在-开始时间;
开始时间=现在;
返回时间已过;
}
main.cpp
duration<double> stepInterval(1.f / 60.f);
duration<double> deltaTime(0);
Clock clock;
while(isRunning)
{
deltaTime += clock.restart();
if(deltaTime > stepInterval)
{
std::cout << deltaTime.count() * 1000 << std::endl;
deltaTime = seconds(0);
}
}
持续时间步长间隔(1.f/60.f);
持续时间增量(0);
时钟;
同时(正在运行)
{
deltaTime+=时钟。重新启动();
if(增量时间>步长间隔)
{
std::cout此代码可能会帮助您。它对我很有效(精度很高):
#包括
#包括
#包括
int main()
{
标准::时钟::高分辨率时钟::时间点上一个=
标准::时钟::高分辨率时钟::现在();
标准::时钟::高分辨率时钟::时间点电流=
标准::时钟::高分辨率时钟::现在();
int i=0;
while(true){
当前=标准::时钟::高分辨率时钟::现在();
if(std::chrono::duration_cast(current-prev).count()>=16000){
prev=当前值;
i++;
std::cout此代码可能会帮助您。它对我很有效(精度很高):
#包括
#包括
#包括
int main()
{
标准::时钟::高分辨率时钟::时间点上一个=
标准::时钟::高分辨率时钟::现在();
标准::时钟::高分辨率时钟::时间点电流=
标准::时钟::高分辨率时钟::现在();
int i=0;
while(true){
当前=标准::时钟::高分辨率时钟::现在();
if(std::chrono::duration_cast(current-prev).count()>=16000){
prev=当前值;
i++;
标准::cout
- 不要对
使用sleep\u。改用sleep\u直到
为止。这将平均从所需帧速率到零的漂移。这是通过睡眠直到当前帧开始加上所需帧持续时间来完成的
使用system\u clock
可以使您的帧速率在很长一段时间内保持准确。没有一个时钟是完美的。但是system\u clock
偶尔会被少量调整到正确的时间。这会使您的帧速率在整个电影长度内都与所需的帧速率保持一致。不要遵循这一点如果您关心的是具有管理员权限的进程,请按总量调整系统时钟。在这种情况下,请使用稳定时钟
创建1/60秒持续时间类型以消除浮点舍入错误
消除代码中的转换常量,如1000
,以减少逻辑错误的可能性
在您的睡眠时间
中,早起一点,然后忙碌地循环直到所需的时间。您必须测试早起的时间。太早会消耗太多的CPU(和电池)。太少,而睡眠时间
在CPU负载较高时偶尔会醒来太晚
总而言之,这可能看起来像:
template <class Clock, class Duration>
void
sleep_until(std::chrono::time_point<Clock, Duration> tp)
{
using namespace std::chrono;
std::this_thread::sleep_until(tp - 10us);
while (tp >= Clock::now())
;
}
int
main()
{
using namespace std;
using namespace std::chrono;
using framerate = duration<int, ratio<1, 60>>;
auto tp = system_clock::now() + framerate{1};
while (isRunning)
{
// do drawing
::sleep_until(tp);
tp += framerate{1};
}
}
我的输出:
...
This frame: 16ms average: 17ms
This frame: 15ms average: 17ms
This frame: 19ms average: 17ms
This frame: 16ms average: 17ms
This frame: 17ms average: 17ms
This frame: 16ms average: 17ms
This frame: 17ms average: 17ms
This frame: 17ms average: 17ms
This frame: 16ms average: 17ms
This frame: 16ms average: 17ms
This frame: 16ms average: 17ms
This frame: 18ms average: 17ms
This frame: 16ms average: 17ms
- 不要对
使用sleep\u。改用sleep\u直到
为止。这将平均从所需帧速率到零的漂移。这是通过睡眠直到当前帧开始加上所需帧持续时间来完成的
使用system\u clock
可以使您的帧速率在很长一段时间内保持准确。没有一个时钟是完美的。但是system\u clock
偶尔会被少量调整到正确的时间。这会使您的帧速率在整个电影长度内都与所需的帧速率保持一致。不要遵循这一点如果您关心的是具有管理员权限的进程,请按总量调整系统时钟。在这种情况下,请使用稳定时钟
创建1/60秒持续时间类型以消除浮点舍入错误
消除代码中的转换常量,如1000
,以减少逻辑错误的可能性
在您的睡眠时间
中,早起一点,然后忙碌地循环直到所需的时间。您必须测试早起的时间。太早会消耗太多的CPU(和电池)。太少,而睡眠时间
在CPU负载较高时偶尔会醒来太晚
总而言之,这可能看起来像:
template <class Clock, class Duration>
void
sleep_until(std::chrono::time_point<Clock, Duration> tp)
{
using namespace std::chrono;
std::this_thread::sleep_until(tp - 10us);
while (tp >= Clock::now())
;
}
int
main()
{
using namespace std;
using namespace std::chrono;
using framerate = duration<int, ratio<1, 60>>;
auto tp = system_clock::now() + framerate{1};
while (isRunning)
{
// do drawing
::sleep_until(tp);
tp += framerate{1};
}
}
我的输出:
...
This frame: 16ms average: 17ms
This frame: 15ms average: 17ms
This frame: 19ms average: 17ms
This frame: 16ms average: 17ms
This frame: 17ms average: 17ms
This frame: 16ms average: 17ms
This frame: 17ms average: 17ms
This frame: 17ms average: 17ms
This frame: 16ms average: 17ms
This frame: 16ms average: 17ms
This frame: 16ms average: 17ms
This frame: 18ms average: 17ms
This frame: 16ms average: 17ms
您可能需要使用特定于操作系统的高精度时钟和计时器。例如,sleep\u for
使用的“正常”计时器可能没有足够的分辨率。您可能需要使用特定于操作系统的高精度时钟和计时器。“正常”计时器例如sleep\u for
使用的计时器可能没有足够的分辨率。我认为使用std::this\u thread::sleep\u for(std::chrono::microseconds(1));
不是个好主意。我认为使用std::this\u thread::sleep\u for(std::chrono::microseconds(1));
不是个好主意。谢谢你的建议。你能检查一下你的代码吗?它对我不起作用,CPU仍然有很高的负载。对不起,我在忙循环中的比较不正确。现在已修复。嗯,我有不同的输出,如31.774 1.5591 28.7145 16.7661
,你知道如何修复它吗?我已经更新了我的答案来测量和报告actual瞬时和平均帧速率。非常好!但不管怎样,有时我的帧速率为0到30毫秒,平均为17毫秒。谢谢你的建议。你能检查一下你的代码吗?它对我不起作用,CPU仍然有很高的负载抱歉,我在忙循环中的比较不正确。现在已修复。嗯,我有不同的输出,如...
This frame: 16ms average: 17ms
This frame: 15ms average: 17ms
This frame: 19ms average: 17ms
This frame: 16ms average: 17ms
This frame: 17ms average: 17ms
This frame: 16ms average: 17ms
This frame: 17ms average: 17ms
This frame: 17ms average: 17ms
This frame: 16ms average: 17ms
This frame: 16ms average: 17ms
This frame: 16ms average: 17ms
This frame: 18ms average: 17ms
This frame: 16ms average: 17ms