2012-01-02 86 views
7

我有一個程序使用Sleep Win32 API調用使線程等待特定的時間。
總之,它通過發送在內存中預取的圖像來模擬相機。我使用Sleep模擬幀速率 - Sleep(1000/fps)系統之間奇怪的「睡眠」行爲

這工作正常,在我的開發系統(英特爾酷睿i5(第一代),Win7的64),但是當我在另一個系統上運行它(英特爾i7-2600 - SandyBridge),睡眠時間完全不同且不準確。

例如, Sleep(16)睡覺周邊32ms
Sleep(3)休眠16ms

在我想有在15ms窗口最小休眠時間的過去,但我沒有得到我的開發系統上的限制。

任何想法?

另外,有沒有更好的方法來實現我模擬器的幀頻?

+0

你談論的Win32 ['Sleep']( http://msdn.microsoft.com/en-us/library/windows/desktop/ms686298.aspx)函數,或者C函數['sleep'](http:/ /pubs.opengroup.org/onlinepubs/009604599/functions/sleep.html)(注意's'的外殼)?您的描述首先提示您的拼寫/命名和(相當通用)標籤。 – 2012-01-02 11:26:36

+0

@ Christian.K - Win32'睡眠' – Itsik 2012-01-02 20:16:20

回答

7

sleep函數保證您將至少睡眠呼叫中指定的數量。它會導致線程暫停,允許在調度程序閒置時切換到其他線程(由線程優先級控制)。換句話說,睡眠線程是而不是保證在指定時間過去後立即運行,因此在一般情況下應避免使用sleep來準確計時。

然而,有些方法可以在Windows上實現更準確的睡眠。您可以撥打timeGetDevCaps來確定支持的最小定時器分辨率,然後在應用程序的早期調用timeBeginPeriod以將定時器分辨率設置爲最小值。請確保在您的應用程序退出之前撥打timeEndPeriod

欲瞭解更多信息,請參閱the Sleep function on MSDN

+0

我試過運行'timeBeginPeriod',但它對持續時間沒有影響。 – Itsik 2012-01-04 13:35:53

+0

你確定它是成功的,即返回'TIMERR_NOERROR' [如MSDN上描述](http://msdn.microsoft.com/en-us/library/windows/desktop/dd757624(v = vs.85).aspx )? – 2012-01-05 09:26:42

1

而不是依靠合理的睡眠行爲或平臺特定的計時器功能(這可能工作得很好,我不知道),你可以像遊戲循環結構。

在循環內部,您調用一個函數爲您提供當前時間。你知道自從畫出最後一幀以來已經過了多長時間,並且決定在恰當的時間自己渲染下一幀。在開發過程中,您應該測量每秒的實際幀數並顯示它。

使用這種方法,tt更容易使您的代碼跨平臺和更準確。此外,您的循環處於控制狀態,而不是將您的代碼構建爲您可能更喜歡的定時器回調。

缺點是「繁忙等待」循環意味着你的進程一直在不停地使用CPU。通過以某種方式明確地抽取用戶界面事件,或者可能使用較短的睡眠時間來緩解這種情況,您可以在循環中產生CPU :-)。

如果你想了解更多關於這種方法,然後開始搜索遊戲循環的材料。

下面是一些關鍵環節:

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