2
\$\begingroup\$

I'm following a tutorial about the time management and, the tutorial shows this function:

double GetFrameTime()
{
    LARGE_INTEGER currentTime;
    __int64 tickCount;
    QueryPerformanceCounter(&currentTime);

    tickCount = currentTime.QuadPart-frameTimeOld;
    frameTimeOld = currentTime.QuadPart;

    if(tickCount < 0.0f)
        tickCount = 0.0f;

    return float(tickCount)/countsPerSecond;
}

The tutorial explains that, this function basically gets the time that one frame takes, but, I don't understand how the variable tickCount can be negative, if the currentTime is increasing all the time (calling this function every frame, obviously), so, is that if really necessary?

\$\endgroup\$
6
  • \$\begingroup\$ What if someone messed up with the memory (access violation kinda bugs)? or whenever you restart timer? Also I'm not sure what would happen if user changes computer time while your code is running. \$\endgroup\$
    – Ali1S232
    Dec 22, 2012 at 20:57
  • \$\begingroup\$ well I know but, in ideal conditions that check wouldn't be necessary right? \$\endgroup\$
    – German
    Dec 22, 2012 at 21:07
  • \$\begingroup\$ I'm not sure, maybe there is some other reason behind that condition. But in general you are developing a game, which I'm pretty sure will not always run in an ideal condition eg. my computer fails to keep track of time, and I don't have to mention how many games I've got installed on my system \$\endgroup\$
    – Ali1S232
    Dec 22, 2012 at 21:14
  • \$\begingroup\$ I have a few comments not worthy of a full answer: 1. It’s also good practice to clamp the frametime to a predefined maximum value which basically represents the framerate above which some algorithms start misbehaving. 2. If you read a tutorial on time management, make sure you read this one, too. \$\endgroup\$ Dec 22, 2012 at 21:47
  • \$\begingroup\$ Is QueryPerformanceCounter sensitive to, for example, the user changing the system time? \$\endgroup\$
    – Liosan
    Dec 22, 2012 at 22:17

1 Answer 1

2
\$\begingroup\$
  1. Even a 64-bit integer can overflow eventually; after increasing for a certain amount of time (exactly how long will depend on QueryPerformanceFrequency(&outvar)), it will eventually roll over, and what used to be a very large number will become a very small number. So when you calculate currentTime.QuadPart - frameTimeOld, that becomes small number - large number == negative number. (This would only happen on one frame, since frameTimeOld then gets overwritten with the small number, and everything would be fine again on the next frame)
  2. According to MSDN, bugs in a computer's BIOS or HAL on a multi-processor machine can result in different values being returned from QueryPerformanceCounter() based upon which processor happens to run the code. So in this sort of case, it could happen far more often.
  3. Probably the real reason: QueryPerformanceCounter() provides its output as a signed 64-bit integer. So you might as well work with it in that form. And since when you're dealing with a signed integer variable it's possible to wind up with a negative number, and that would cause problems if it happened, it's just good practice to guard against it.
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .