Моя программа должна вызывать событие каждые 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 минуты, их время составляло всего около 160 секунд, и я обнаружил, что, когда таймер приближается к 150 секундам, увеличение времени просто замедляется до полной остановки. Я отслеживал dt в каждом цикле, и, похоже, он ничем не отличается от того, что было в начале.
Может ли все это быть вызвано навязчивой оптимизацией компилятора?
32-битная ошибка с плавающей точкой?
Я буду продолжать изучать это, но любая помощь приветствуется.
Я все еще учусь, поэтому использую книгу DirectX.
Я использую временной код из демонстрации, которую предоставила книга:
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;
}