std::chrono 不同的结果 - 固定时间步长循环

std::chrono different results - fixed time step loop

谁能帮我找出不同之处?因为第一个代码:

#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;
      }
  }
}

输出:30,第二个代码:

#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;
      }
  }
}

输出:60;

唯一的区别是在第二个示例中使用了 "end" 变量。在我看来,它不应该造成这样的差异。我的意思是, steady_clock::now() 和 end = steady_clock::now() 不完全一样吗?

不同的是这里

  accumulator += steady_clock::now() - begin;
  counter += steady_clock::now() - begin;

now() return 两个不同值的两个实例,因此 counter 不会与 accumulator 同步,下一个 if 条件将更早触发一次迭代,因为与

相比
  end = steady_clock::now();
  accumulator += end - begin;
  counter += end - begin;

因为这里 accumulatorcounter 都增加了相同的数量。

您可以通过将两个语句的顺序更改为

来验证这一点
  counter += steady_clock::now() - begin;
  accumulator += steady_clock::now() - begin;

这将产生非常不可预测的输出 in my case i got a 117

为了使代码更具可读性,我会这样写:

auto delta = end - begin;
accumulator += delta;
counter     += delta;

避免多次输入完全相同的内容总是好的。在这种情况下,它们以相同的数量递增真的很重要,那么为什么不在代码中明确说明呢?!

TL;DR steady_clock::now()end = steady_clock::now() 是 "the same",但 steady_clock::now() 不会 return 相同调用两次时的值。