sleeping-to-save-cpu

本文探讨了在等待页面翻转时使用Sleep()函数来释放CPU资源的方法及其限制。作者建议在Windows环境下谨慎使用Sleep(),因为它可能导致CPU速度降低且无法精确控制睡眠时间。此外,Sleep()不会因窗口事件而唤醒。文章提供了替代方案,如使用MsgWaitForMultipleObjectsEx()实现警觉式睡眠。

Link: http://www.mindcontrol.org/~hplus/sleeping-to-save-cpu.html

 

Q: Hey, I'm spending a lot of time spinning in the graphics driver, waiting for a page flip, because I'm v-synced. Wouldn't it be better to Sleep() away that time, to give up some CPU to other applications?

A: That should work, with some caveats. I'm assuming Windows here (because otherwise you'd be talking about usleep() :-)

What you're doing is trying to make a time-sharing consumer OS do what's basically a real-time task. This isn't super easy, but can be done with some success.

Sleep()-ing is very jittery on DOS-based Windows. At best, you get +/- 20 ms precision, which is too low to use for interactive applications that want smooth frame rate. So detect Win98/ME and turn off sleeping, or have a check-box to turn it off.

Sleep() signals to the OS that you have nothing better to do, which will cause SpeedStep CPUs to slow down. Unfortunately, this means that your main loop will run at the slower speed, so you'll be falling behind, and won't be sleeping. Finally, the OS will notice you're not sleeping, and up the CPU speed. Then you'll start sleeping again, and the OS turns on SpeedStep... Detect SpeedStep and turn off sleeping, or have a check-box to turn it off.

Sleep() may wake up later than you tell it to (as I said, jitter), although it's pretty good on NT-based Windows (such as Windows XP). Thus, I'd set a wake-up point about 2 milliseconds before when I need to swap frames, and just accept that I'll be spinning for 2 milliseconds each frame (minus wake-up delay). If there's less than 2 ms left before flipping, don't sleep at all. You may find that wake-up precision is better if you raise the priority class of your application and the priority of your thread.

Sleep() does not wake up if there are windows events waiting for your window. For better interactivity, you may want to create an event that you never set, and then call MsgWaitForMultipleObjectsEx() with a time-out. This is known as an "alertable" sleep, and will wake you up if there are suddenly events delivered to your application (such as mouse movement). You could even run your Windows message pump that way: sleep and/or handle messages until 2 milliseconds before it's time to flip; then flip; then handle any remaining Windows messages before you go on to simulate and render the next frame.

Good luck!

[Summary]

Sleep会有精度误差, 而且会SpeedStep CPUs to slow down; 并且在有windows events 也不能被唤醒。

SleepEx 好像是"alertable" sleep。

Solution: Create an event that you never set, and then call MsgWaitForMultipleObjectsEx() with a time-out

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值