系统之间奇怪的“睡眠”行为

时间:2012-01-02 09:29:02

标签: c++ winapi timing

我有一个使用Sleep Win32 API调用的程序让线程等待特定的时间。
简而言之,它通过发送预存在内存中的图像来模拟相机。我正在使用Sleep来模拟帧速率 - Sleep(1000 / fps)

这在我的开发系统(Intel i5(第1代),Win7 64)中运行良好,但是当我在另一个系统(Intel i7-2600 - SandyBridge)上运行时,睡眠时间完全不同且不准确。

例如, Sleep(16)大约在32ms左右睡觉 Sleep(3)16ms

休眠

过去我认为在15ms的窗口中有最小的睡眠时间,但我没有在我的开发系统上受到限制。

任何想法?

另外,有没有更好的方法来实现我的模拟器的帧速率?

2 个答案:

答案 0 :(得分:7)

sleep功能可确保您至少睡眠至呼叫中指定的数量。它导致线程挂起,允许在调度程序的空闲时切换到其他线程(由线程优先级控制)。换句话说,睡眠线程保证在指定时间过后立即运行,因此在一般情况下应避免使用sleep进行准确计时情况下。

然而,有一些方法可以在Windows上实现更准确的睡眠。您可以调用timeGetDevCaps来确定支持的最小计时器分辨率,然后在应用程序中提前调用timeBeginPeriod,将计时器分辨率设置为最小值。请务必在退出应用程序之前致电timeEndPeriod

有关详细信息,请参阅the Sleep function on MSDN

答案 1 :(得分:1)

不是依赖于准确的睡眠行为或平台特定的计时器功能(可能效果很好,我不知道),你可以像游戏循环一样构建它。

在循环内部,您可以调用函数来为您提供当前时间。您可以确定自绘制最后一帧以来已经过了多长时间,并决定何时在正确的时间自己渲染下一帧。在开发过程中,您应该测量每秒的实际帧数并显示它。

使用这种方法,可以更轻松地使您的代码跨平台并且更加准确。此外,您的循环处于控制状态,而不是将您的代码构造为您可能也喜欢的计时器回调。

缺点是“忙等待”循环意味着您的进程将不必要地一直使用CPU。为了减轻这种情况,你可以通过以某种方式明确地抽取用户界面事件或者使用更短的睡眠来产生循环中的CPU :-)。

如果您想了解有关此方法的更多信息,请开始在Google游戏循环中搜索材料。

以下是一些必要的链接:

http://www.koonsolo.com/news/dewitters-gameloop/

http://gafferongames.com/game-physics/fix-your-timestep/

关于SO的讨论:

https://gamedev.stackexchange.com/questions/1589/fixed-time-step-vs-variable-time-step