Windows中有很多應用程序觸發代碼的示例,它們在相當高且穩定的幀率下不會觸發CPU。例如,WPF/Silverlight/WinRT應用程序可以執行此操作。瀏覽器和媒體播放器也是如此。他們究竟如何做到這一點,以及爲了從Win32應用程序中獲得相同的效果,我會調用哪些API?Win32遊戲循環不會激增CPU
當然,時鐘輪詢不起作用,因爲這會激增CPU。 Sleep()
也沒有,因爲你最多隻能獲得大約50ms的粒度。
Windows中有很多應用程序觸發代碼的示例,它們在相當高且穩定的幀率下不會觸發CPU。例如,WPF/Silverlight/WinRT應用程序可以執行此操作。瀏覽器和媒體播放器也是如此。他們究竟如何做到這一點,以及爲了從Win32應用程序中獲得相同的效果,我會調用哪些API?Win32遊戲循環不會激增CPU
當然,時鐘輪詢不起作用,因爲這會激增CPU。 Sleep()
也沒有,因爲你最多隻能獲得大約50ms的粒度。
他們正在使用多媒體計時器。您可以在MSDN上找到信息here
在每個多媒體計時器事件上,只有視圖無效(與f = InvalidateRect)。繪圖發生在WM_PAINT
/OnPaint
處理程序中。
其實睡眠沒有問題。
您可以使用QueryPerformanceCounter/QueryPerformanceFrequency組合來獲取非常準確的時間,並且平均而言,您可以創建一個循環,該循環恰好在它應該達到的時間平均向前跳動。
我從來沒有看到睡眠錯過它的最後期限多達50毫秒,但是,我看到很多天真的定時器漂移。即積累一小段延遲並確實更新不明顯的不規則間隔。這是造成幀率不均勻的原因。
如果您在每個第n幀播放一個很短的蜂鳴聲,這是非常可聽的。
此外,邏輯和渲染可以彼此獨立運行。 CPU可能看起來並不那麼忙,但我敢打賭,GPU在努力工作。
現在,大約不佔CPU。 CPU使用率只是某個進程在給定示例下花費的CPU時間的細分(線程調度器實際上會跟蹤這個)。如果你的遊戲目標是30赫茲。你每幀限制在33ms,否則你會落後(CPU太慢或代碼太慢),如果你不能達到這個目標,你將不會以30Hz運行,如果你在33ms以下那麼你可以產生處理器時間,有效地釋放資源。
This對您來說也可能是一種有趣的閱讀。
在一個側面說明,而不是產生時間,你可以有效地爲未來的計算做準備。有些遊戲不在最重的負載下時,實際上會將排序和內存碎片整理做一些事情,最後總結一下。
看起來這實際上已經過時了[排隊計時器](http://blogs.msdn.com/b/larryosterman/archive/2005/09/08/462477.aspx)。 – 2012-04-18 12:04:33
在[timeSetEvent](http://msdn.microsoft.com/en-us/library/windows/desktop/dd757634(v = vs.85).aspx)的信息頁面上,Ken Smith指出多媒體計時器仍然是Windows中只有可靠的高分辨率計時器。我想你應該看看兩者,看看最適合你的應用程序。 – 2012-04-18 12:20:47
Bleh,我希望他們在棄用東西之前做出正確的選擇。再說一遍,我認爲這足以應付一場比賽...... – 2012-04-18 20:55:43