您的位置:首页 > 其它

[win32] timeGetTime,GetTickCount在多核CPU上时间倒流

2016-07-08 13:13 501 查看
游戏渲染循环中,每次都要用timeGetTime或者GetTickCount,来取得时间,作为deltaTime。但是发现在Win7上,有时候取到的是负数。这是多核CPU导致的问题。

大致有三种方案:

1. 判断deltaTime,如果小于等于0,那么忽略这次更新。SM里面用的就是这个方案。

2. 使用SetThreadAffinityMask将线程绑定到一个指定的CPU核上,但是SM里面说XP下,会导致帧率下降10%。

3. 在取时间前后加上timeBeginPeriod(1);和timeEndPeriod(1);
这个方法是设置最大的时间精度,但是msdn上说,这个值是整个windows共用的值,如果设的精度比较高,那么线程之间切换回比较频繁,可能会让电脑进入不了power-saving modes。这个方法试了,可以解决问题,但是msdn上说的顾虑,这些没考虑过。

综合来看,还就是最简单的方法1最省心。

代码示例,用了龙书里面的代码:

int d3d::EnterMsgLoop( bool (*ptr_display)(float timeDelta) )
{
MSG msg;
::ZeroMemory(&msg, sizeof(MSG));

static float lastTime = (float)timeGetTime();

while(msg.message != WM_QUIT)
{
if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
else
{
// 通过timeBeginPeriod和timeEndPeriod解决时光倒流
// 			timeBeginPeriod(1);
// 			float currTime  = (float)timeGetTime();
// 			timeEndPeriod(1);
// 			float timeDelta = (currTime - lastTime)*0.001f;
//
// 			ptr_display(timeDelta);
// 			lastTime = currTime;

// 通过忽略负数,解决时光倒流
float currTime  = (float)timeGetTime();
float timeDelta = (currTime - lastTime)*0.001f;

if(timeDelta > 0)
{
ptr_display(timeDelta);
lastTime = currTime;
}
else
{
; // do nothing
}
}
}
return msg.wParam;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  windows