Could somebody help me to find out where is the difference? Because first code:
#include <iostream>
#include <chrono>
#include <ratio>
using namespace std::chrono;
const nanoseconds timePerFrame = duration_cast<nanoseconds>(duration<steady_clock::rep, std::ratio<1, 60>>(1));
nanoseconds accumulator(0);
nanoseconds counter(0);
steady_clock::time_point begin;
int i = 0;
int main()
{
while(true)
{
begin = steady_clock::now();
while(accumulator >= timePerFrame)
{
accumulator -= timePerFrame;
++i;
}
accumulator += steady_clock::now() - begin;
counter += steady_clock::now() - begin;
if(counter >= seconds(1))
{
std::cout << i << std::endl;
break;
}
}
}
Outputs: 30, and a second code:
#include <iostream>
#include <chrono>
#include <ratio>
using namespace std::chrono;
const nanoseconds timePerFrame = duration_cast<nanoseconds>(duration<steady_clock::rep, std::ratio<1, 60>>(1));
nanoseconds accumulator(0);
nanoseconds counter(0);
steady_clock::time_point begin;
steady_clock::time_point end;
int i = 0;
int main()
{
while(true)
{
begin = steady_clock::now();
while(accumulator >= timePerFrame)
{
accumulator -= timePerFrame;
++i;
}
end = steady_clock::now();
accumulator += end - begin;
counter += end - begin;
if(counter >= seconds(1))
{
std::cout << i << std::endl;
break;
}
}
}
Outputs: 60;
The only one difference is using "end" variable in second example. In my opinion it shouldn't cause such difference. I mean, isn't steady_clock::now() exactly the same as end = steady_clock::now()?
The difference is that here
accumulator += steady_clock::now() - begin;
counter += steady_clock::now() - begin;
the two instances of now()
return 2 different values, thus counter
wont be in sync with accumulator
and the next if condition will trigger one iteration earlier as compared to
end = steady_clock::now();
accumulator += end - begin;
counter += end - begin;
because here both, accumulator
and counter
are incremented by the same amount.
You can verify this by changing the order of the two statements to
counter += steady_clock::now() - begin;
accumulator += steady_clock::now() - begin;
that will yield quite unpredicatable output in my case i got a 117.
To make the code even more readable I would write it like this:
auto delta = end - begin;
accumulator += delta;
counter += delta;
It is always good to avoid typing exactly the same thing more than once. In this case it really matters that they are incremented by the same amount, so why not make it explicit in the code?!
TL;DR steady_clock::now()
is "the same" as end = steady_clock::now()
, but steady_clock::now()
wont return the same value when you call it twice.