2009年6月16日 星期二

Sleep(1)精準嗎?

在用Sleep(1)函數的時候, 遇到一個怪現象, 就是在不同電腦下, 使用Sleep(1)的精準度會不一樣.

我的測試的方法, 是使用FPS來當測試依據 , 而FPS指的是 "Frame Per Second", 也就是每秒畫面更新的次數, 而FPS對遊戲程式也相當重要, 它會影響畫面的流暢(閃爍和停格等), 下面code為測試程式的source code:

void FPSTest(void)
{
static int Frames = 0; //更新的次數
static int UpdateTime = 1000; //多久算一次FPS
static int LastTime = 0; //上次計算FPS的時間
static double FPS = 0;

Frames++; // 增加更新的次數

if(GetTickCount()-LastTime>UpdateTime) // 如果時間超過,該更新
{
FPS = ((double)Frames/(double)(GetTickCount()-LastTime))*1000.0; // FPS的計算公式
LastTime = GetTickCount(); // 設定時間,給下次用
Frames = 0; // 更新次數歸0

}
}


int _tmain(int argc, _TCHAR* argv[])
{

while(
1)

{
FPSTest();

Sleep(1);

}
return 0;
}


以下是我的測試結果:

(1)
TOSHIBA Intel Core 2 Duo T550 1.83GHZ WinXP SP3
平均 FPS = 512

(2)
ACER Intel Core 2 Duo T7300 2.00GHZ Windows 7 Ultimate
平均 FPS = 64


去請教Google大師, 找到有部份文章提到,多媒體程式庫中有個 timeBeginPeriodAPI,可以設定時間解析度, 用法也很簡單,需要包含mmsystem.h和連結 winmm.lib, 因此將原本測試程式改成 :

int _tmain(int argc, _TCHAR* argv[])
{

timeBeginPeriod(1);
while(1)
{
FPSTest();

Sleep(1);

}
timeEndPeriod(1);
return 0;
}


重新測試結果馬上大不相同,Sleep不再delay,原則上會逼近所要求的等待時間:

(1)
TOSHIBA Intel Core 2 Duo T550 1.83GHZ WinXP SP3
平均 FPS = 512


(2)
ACER Intel Core 2 Duo T7300 2.00GHZ Windows 7 Ultimate
平均 FPS = 1000


注意 :
使用timeBeginPeriod時要注意,原則上調動它會造成系統不必要的負擔,也會改變系統的Sleep()函數的精準度, 記得不用了馬上timeEndPeriod恢復原狀。

參考資料 :


沒有留言:

張貼留言