here's my code for sending messages every 3 seconds for 10 times. but it ignores all of if statements in while(true)
double current;
double freq;
QueryPerformanceFrequency((LARGE_INTEGER*)&freq);
QueryPerformanceCounter((LARGE_INTEGER*)¤t);
float totalTime = 0.f;
float counter = 0.f;
while (true)
{
double previous = current;
QueryPerformanceCounter((LARGE_INTEGER*)¤t);
double deltaTime = (current - previous) / freq;
totalTime = deltaTime;
counter = deltaTime;
if (counter > 3.f)
{
cout << "msg Sent" << totalTime << "\n";
counter = 0;
}
if (totalTime > 30.f)
{
break;
}
}
weird thing is that if I print out two of those values in the middle, it works fine.
double current;
double freq;
QueryPerformanceFrequency((LARGE_INTEGER*)&freq);
QueryPerformanceCounter((LARGE_INTEGER*)¤t);
float totalTime = 0.f;
float counter = 0.f;
while (true)
{
double previous = current;
QueryPerformanceCounter((LARGE_INTEGER*)¤t);
double deltaTime = (current - previous) / freq;
totalTime = deltaTime;
counter = deltaTime;
cout << totalTime << "\n";
cout << counter << "\n";
if (counter > 3.f)
{
cout << "msg Sent" << totalTime << "\n";
counter = 0;
}
if (totalTime > 30.f)
{
break;
}
}
I think it happened because of compiler optimization. if I'm right, is there any way to stop compiler messing up my code?
LARGE_INTEGER current;
LARGE_INTEGER freq;
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(¤t);
float totalTime = 0.f;
float counter = 0.f;
while (true)
{
LARGE_INTEGER previous = current;
QueryPerformanceCounter(¤t);
double deltaTime = (current.QuadPart - previous.QuadPart) / static_cast<double>(freq.QuadPart);
totalTime = deltaTime;
counter = deltaTime;
if (counter > 3.f)
{
cout << "msg Sent" << totalTime << "\n";
counter = 0;
}
if (totalTime > 30.f)
{
break;
}
}
This time I followed c rule and the result is same. So it's not the trouble of casting. and it also works when i put two prints in the middle.
CodePudding user response:
It is likely that the problem is due to deltaTime
being significantly smaller than 3.f
and 30.f
.
Since, unless either if
branch is taken, the loop body doesn't do anything except measure a clock, the time between iterations is likely to be very small. Initially, this won't be a problem and deltaTime
will be correctly added to counter
and totalTime
. However, as these variables increase in size, they will eventually become so large that deltaTime
will fall below the precision provided by double
. When this happens, adding deltaTime
will cease to increase these variables as the result will round out to exactly the original value.
This is made worse by using float
to represent counter
and totalTime
, which is the floating point type with the lowest precision, meaning the problem will appear for at larger values of deltaTime
than if a better floating point type was used.
By adding several std::cout
the loop body may be slowed enough that deltaTime
is always large enough to be meaningful relative to counter
and totalTime
.
Instead of counting time using imprecise floating point types, use integer types when possible to avoid this problem. Based on freq
you can calculate how many ticks are equivalent to your 3.f
and 30.f
constants. You can then just count ticks and compare that count to the calculated limits.