Привет всем. Задача такова: я хочу обновлять некие циклические данные как можно чаще. Сначала я попытался сделать так: в вечном цикле делал некие действия, замерял в наносекундах (через 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));
}