Задать вопрос
UndeadDragon
@UndeadDragon
Разработчик ПО на C++, Qt, Python и др.

C++ std::chrono::high_resolution_clock наносекундная точность?

Привет всем. Задача такова: я хочу обновлять некие циклические данные как можно чаще. Сначала я попытался сделать так: в вечном цикле делал некие действия, замерял в наносекундах (через std::chrono::high_resolution_clock) занявшее это время, в соответствии с ним двигал что-то, что мне надо, и повторял. И хотя в коде ниже "Average error" выводила очень небольшое значение в пару наносекунд (я каждый круг проверяю время, в тесте круг должен был занимать одну секунду), дебаговый вывод времени и проверочный таймер timer2 выводили совсем другие результаты - они говорили, что круг совершается занчительно быстрее, за 600 миллисекунд. Это подтверждалось и зрительно, что слишком быстро. Тогда я воткнул sleep_for на пару миллисекунд (пробовал разное время). Стало так: Average error показывает куда большую ошибку в наносекундах, но зрительно и в timer2 все намного лучше, timer2 показывает, что круг выполняется на 1-5 мс быстрее. Но я бы хотел достичь большей точности - как я понимаю, Linux такое должен мочь определять по тактам. Но вот что-то не выходит. Код привожу ниже. Надеюсь кто-нибудь поможет разобраться.
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));
  }
  • Вопрос задан
  • 2274 просмотра
Подписаться 2 Оценить Комментировать
Пригласить эксперта
Ответы на вопрос 1
@Xano
проверьте точность high_resolution_clock, вполне вероятно, что она далека от наносекунд( у меня, например high_resultion_clock определено как "typedef system_clock high_resolution_clock;", и их точность составляет 50 миллисекунд )
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы