M
M
Maxim Kuprashevich2015-07-16 11:53:31
Qt
Maxim Kuprashevich, 2015-07-16 11:53:31

C++ std::chrono::high_resolution_clock nanosecond precision?

Hi all. The challenge is this: I want to update some cyclical data as often as possible. At first I tried to do this: in an eternal loop, I did some actions, measured in nanoseconds (via std::chrono::high_resolution_clock) the time that had taken this time, moved something that I needed in accordance with it, and repeated. And although in the code below "Average error" outputted a very small value of a couple of nanoseconds (I check the time every lap, in the test the lap should take one second), the debug output of time and the check timer timer2 displayed completely different results - they said that the lap is completed much faster, in 600 milliseconds. This was also confirmed visually, which was too fast. Then I stuck sleep_for for a couple of milliseconds (tried different times). It became like this: Average error shows a much larger error in nanoseconds, but visually and in timer2 everything is much better, timer2 shows that the circle is 1-5 ms faster. But I would like to achieve more accuracy - as I understand it, Linux should be able to determine this by clocks. But here's something that doesn't work. I provide the code below. Hope someone can help figure it out.

std::chrono::time_point<std::chrono::high_resolution_clock> start =
      std::chrono::high_resolution_clock::now();
  std::chrono::time_point<std::chrono::high_resolution_clock> end = start;
  int diff = Global::DOUBLE_ZERO;
  const double something_per_nanosec = ...;
  const int nanscs_for_circle_must_be = ...;
  int nanscs_for_circle_is = Global::INT_ZERO;
  is_running_ = true;
  double step = Global::DOUBLE_ZERO;
  auto MeasureTime = [&start, &end, &diff, &step, something_per_nanosec]() {
    auto old_start = start;
    start = std::chrono::high_resolution_clock::now();
    end = std::chrono::high_resolution_clock::now();
    diff = std::chrono::duration_cast<std::chrono::nanoseconds>(end - old_start).count();
    step = ((double)diff) * something_per_nanosec;
  };

  float errors = 0.0;
  float circles = 0.0;


  timer.start();
  QTime timer2;
  timer2.start();
  qDebug() << timer.clockType();
  for (;MeasureTime(), isRunning() == true; ) {

    if (circle was done
        && nanscs_for_cirle_is != 0) {
      if (nanscs_for_cirle_is != nanscs_for_cirle_must_be) {
        errors += nanscs_for_cirle_must_be
                   - nanscs_for_cirle_is;
        ++circles;
        qDebug() << "Average error: " << (errors / circles) << nanscs_for_cirle_must_be << nanscs_for_cirle_is;
        qDebug() << "Total error :" << errors;
        qDebug() << timer2.restart();
        nanscs_for_cirle_is = 0;

      }
    }

    do something();

    nanscs_for_cirle_is += diff;
    std::this_thread::sleep_for(std::chrono::duration<double, std::milli>(5));
  }

Answer the question

In order to leave comments, you need to log in

1 answer(s)
X
Xano, 2015-07-16
@Xano

check the accuracy of high_resolution_clock, it is likely that it is far from nanoseconds (for example, I have high_resultion_clock defined as "typedef system_clock high_resolution_clock;", and their accuracy is 50 milliseconds )

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question