我的程序应该每180秒触发一次事件。
mFoodSpawnTime += dt;
if (mFoodSpawnTime > mFoodSpawnCycleLength)
{
..... etc;
}
mFoodSpawnCycleLength = 180.0f,而mFoodSpawnTime是另一个每次循环累积时间的浮点数。
我的问题是,如果mFoodSpawnCycleLength大约是180.0f,那么在发布版本上它似乎永远不会到达,mFoodSpawnTime最多花费10分钟为>比mFoodSpawnCycleLength!我已经定时调试构建,它确实在180秒后执行循环,并且我已经使用秒表进行了验证。返回发布版本:只要mFoodSpawnCycleLength不接近180.0f,它也匹配秒表并执行代码。我曾经把它设置为120.0f,当它执行秒表时读取2分30秒。没有#ifdef DEBUG代码可能导致此问题。 所以我所说的是:mFoodSpawnCycleLength越接近180.0f,时间变得越精确,但仅限于发布版本!
我刚刚打印出mFoodSpawnTime,当我的时钟读取3分钟时,它的时间只有160s左右,我发现当计时器接近150秒时,时间增量只会减慢到停止。我在每个循环中跟踪了dt,它似乎与开头没有任何不同。
这可能都是由侵入式编译器优化引起的吗? 32位浮点错误? 我将继续研究这个问题,但感谢任何帮助。
我还在学习,所以我正在使用DirectX Book。 我使用了本书提供的演示中的时间码:
int D3DApp::run()
{
MSG msg;
msg.message = WM_NULL;
__int64 cntsPerSec = 0;
QueryPerformanceFrequency((LARGE_INTEGER*)&cntsPerSec);
float secsPerCnt = 1.0f / (float)cntsPerSec;
__int64 prevTimeStamp = 0;
QueryPerformanceCounter((LARGE_INTEGER*)&prevTimeStamp);
while(msg.message != WM_QUIT)
{
// If there are Window messages then process them.
if(PeekMessage( &msg, 0, 0, 0, PM_REMOVE ))
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
// Otherwise, do animation/game stuff.
else
{
if( mTimeReset )
{
QueryPerformanceCounter((LARGE_INTEGER*)&prevTimeStamp);
mTimeReset = false;
}
if( !isDeviceLost() )
{
static float frameLimit = 0.0f;
__int64 currTimeStamp = 0;
QueryPerformanceCounter((LARGE_INTEGER*)&currTimeStamp);
float dt = (currTimeStamp - prevTimeStamp)*secsPerCnt;
if (dt > 2.0f) dt = 0.0f;
frameLimit +=dt;
updateScene(dt);
if (frameLimit > 0.0167f)
{
drawScene();
frameLimit = 0.0f;
}
// Prepare for next iteration: The current time stamp
// the previous time stamp for the next iteration.
prevTimeStamp = currTimeStamp;
}
}
}
return (int)msg.wParam;
}
答案 0 :(得分:5)
你可能想尝试在这里使用double而不是float。在这种情况下,性能差异将是最小的,我怀疑你可能遇到一个问题,你在一个大数字中添加一个非常小的数字 - 保持大数字的浮点值不变。
Floats只能提供大约六位数的精度。如果性能计数器周期大约为ns,则当frameLimit达到几毫秒时,您将开始遇到问题。
调试模式往往会运行得更慢,导致更大的增量,这可能就是你没有看到问题的原因。