Russian Qt Forum

Qt => Общие вопросы => Тема начата: Alexxey593 от Сентябрь 24, 2010, 18:45



Название: QTimer слишком неточный
Отправлено: Alexxey593 от Сентябрь 24, 2010, 18:45
Мне надо, чтобы таймер срабатывал 25 раз в секунду.
Код:
...
QTimer timer;
...
connect(&timer, SIGNAL(timeout()), this, SLOT(timerSlot()));
...
timer.start(1000/25);

Но реально таймер срабатывает 22 раза в секунду (видно по скорости обработки данных...).
Написал даже небольшую прожку с двумя таймерами: один таймер инкрементирует переменную, другой раз в секунду выводит эту переменную на экран. Получаются очень странные результаты. Таймер на одну мс срабатывал примерно тысячу раз (как и должно быть). На интервалах от 30 до 40 мс он все время срабатывает 22 раза в секунду. 50 мс срабатывал 20 раз (опять верно). В общем на каких-то значениях задержки QTimer работает как надо, а на каких-то очень криво... Пробовал компилировать на Qt 4.6.2, 4.6.3, 4.7.0, статические сборки и обычные. Запускал на WinXP и Win7. Везде одни и те же результаты. Точно так же работают QBasicTimer и QObject::timerEvent.
Пришлось запустить таймер на 20 мс (50 тиков в секунду) и обрабатывать каждый второй тик... Но хотелось бы разобраться в чем проблема...


Название: Re: QTimer слишком неточный
Отправлено: Авварон от Сентябрь 24, 2010, 19:06
погуглите, был блог (на Qt Labs) о точном таймере... его вроде даже хотели в 4.7 сделать


Название: Re: QTimer слишком неточный
Отправлено: kuzulis от Сентябрь 24, 2010, 19:34
Сколько уже поистрепали эту тему.. Не получите вы точность выше 55 мс, т.к учитывайте время на переключение контекста и т.п. Да и вообще, прерывания от таймера тикают с частотой 18,2 Гц.. Так что увы. Забудьте.


Название: Re: QTimer слишком неточный
Отправлено: Sancho_s_rancho от Сентябрь 24, 2010, 19:52
Сколько уже поистрепали эту тему.. Не получите вы точность выше 55 мс, т.к учитывайте время на переключение контекста и т.п. Да и вообще, прерывания от таймера тикают с частотой 18,2 Гц.. Так что увы. Забудьте.
Ну не надо так категорично. Есть же high precision/resolution таймеры в современных машинах. В виндовс надо копать куда-то в сторону QueryPerformanceCounter().


Название: Re: QTimer слишком неточный
Отправлено: lit-uriy от Сентябрь 24, 2010, 20:21
>>огуглите, был блог (на Qt Labs) о точном таймере... его вроде даже хотели в 4.7 сделать
там, в блоге, как раз говорили о том, что неточный таймер - это здорово, т.к. снижается энергопотребление в портативных устройствах


Название: Re: QTimer слишком неточный
Отправлено: lit-uriy от Сентябрь 24, 2010, 20:27
>>В виндовс надо копать куда-то в сторону QueryPerformanceCounter().
не путайте счётчик с таймером. Счётчик - справочное (ведомое) устройство, таймер - ведущее устройство (оно заставляет кого-то что-то сделать)

Быстрый счётчик (тиков) сделать просто (например, тут (http://www.forum.crossplatform.ru/index.php?showtopic=3997))


Название: Re: QTimer слишком неточный
Отправлено: maxxant от Сентябрь 27, 2010, 09:02
чтобы увеличить точность таймера под виндой можно вызвать timeBeginPeriod(1) - это стандартная функция во всех играх, уменьшает квант времени на потоки. (стандартно квант обычно 10-15 мс). Если под линукс, то никак, вернее, только под рутом параметрами ядра с версии 2.6.24.

почитать про timeBeginPeriod() и т.д можно где-нибудь здесь:
http://www.dtf.ru/articles/read.php?id=39888&page=2

в 4.7 появился более точный таймер (без сигналов) не подверженный системной или ручной подводке времени (например NTP)
http://doc.qt.nokia.com/4.7/qelapsedtimer.html

ну и да QTimer в принципе не может обеспечить хорошую точность, поскольку сигнал испускается при выполнении QApplication::exec() или если в отдельном потоке QThread::exec(), то есть, если поток притормозил в выполнении чего-либо на 0.5 сек, значит и таймер опоздает на 0.5 сек.



Название: Re: QTimer слишком неточный
Отправлено: SASA от Сентябрь 27, 2010, 11:31
Мне надо, чтобы таймер срабатывал 25 раз в секунду.

Если не секрет, зачем?


Название: Re: QTimer слишком неточный
Отправлено: navrocky от Сентябрь 27, 2010, 19:49
Мне надо, чтобы таймер срабатывал 25 раз в секунду.

Если не секрет, зачем?

25 кадр же!

sleep вроде большую точность дает чем таймер,
А для больше точности можно совместить маленький sleep с отсчетом времени через QTime.start/elapsed, например.

Крутишь эту штуку в потоке и испускаешь сигналы, как настоящий таймер )

Жаль что в Qt sleep нет, можно взять его уз буста %) или сгородить свой на дефайнах для каждой ОС.
Пардон, гоню - QThread::sleep же, правда он зачем-то protected но ничего страшного...