我想写一个游戏循环并测量渲染所需的时间。在循环结束时,我希望线程睡眠一段时间,以免耗尽CPU。现在我想每秒循环60次。
下面是我想到的最小例子:
#include <iostream>
#include <Windows.h>
class Clock {
public:
Clock() : m_Start(), m_Elapsed(0) {}
double AbsoluteTime() {
LARGE_INTEGER current_time;
QueryPerformanceCounter(¤t_time);
LARGE_INTEGER frequency;
QueryPerformanceFrequency(&frequency);
return static_cast<double>(current_time.QuadPart) / frequency.QuadPart;
}
void Start() {
m_Start = AbsoluteTime();
}
double GetElapsed() {
double current_time = AbsoluteTime();
m_Elapsed = current_time - m_Start;
return m_Elapsed;
}
private:
double m_Start;
double m_Elapsed;
};
int main() {
Clock clock;
Clock fpsClock;
int frameCount = 0;
while (true) {
clock.Start();
// Do some rendering stuff....
double elapsed = clock.GetElapsed();
double delay = (1.0 / 60.0) - elapsed;
if (delay > 0) {
Sleep(static_cast<DWORD>(delay * 1000));
}
frameCount++;
if (fpsClock.GetElapsed() > 1.0) {
std::cout << "FPS: " << frameCount << std::endl;
fpsClock.Start();
frameCount = 0;
}
}
return 0;
}
然而,当执行这段代码时,我得到的只是每秒打印33帧。我真的不知道为什么会发生这种情况。如果我不使用睡眠方法,我得到超过4600帧一秒。所以这不可能是性能问题。有没有人遇到过这种情况,或者知道如何解决?
1条答案
按热度按时间bttbmeg01#
Sleep函数的分辨率有限:
系统时钟以恒定速率“滴答”。如果 dwMilliseconds 小于系统时钟的分辨率,则线程可能会休眠少于指定的时间长度。如果 dwMilliseconds 大于一个刻度但小于两个刻度,则等待时间可以介于一个和两个刻度之间,依此类推。要提高休眠间隔的精度,请调用
timeGetDevCaps
函数确定支持的最小计时器分辨率,并调用timeBeginPeriod
函数将计时器分辨率设置为最小值。调用timeBeginPeriod
时要小心,因为频繁的调用会严重影响系统时钟、系统电源使用和调度程序。我建议使用SetWaitableTimer和SleepEx函数。