Russian Qt Forum

Qt => Многопоточное программирование, процессы => Тема начата: Alex_C от Июнь 21, 2012, 20:17



Название: Аналог виндового мультимедиа таймера в Qt
Отправлено: Alex_C от Июнь 21, 2012, 20:17
Как известно , в винде есть так называемый мультимедиа таймер, отличие от простого таймера в том, что он выполняется в четко заданные промежутки времени , а не когда освободится система, как в обычном таймере, и в том, что вызываемая в нем callback-функция вызывается в отдельном потоке. Вопрос - понятно что под Qt можно использовать непосредственно сам мультимедиа таймер, но но это получается платформазависимый код. А как реализовать мультимедиа таймер средствами Qt?


Название: Re: Аналог виндового мультимедиа таймера в Qt
Отправлено: Bepec от Июнь 21, 2012, 20:50
Кхм. Задам глупый вопрос насчёт мультимедиа таймера:

То есть вы хотите сказать, что на мультимедиа драйвер не распространяется погрешность Windows в подсчёте времени? Которая заявлена как 15+-(частота кварца компа) мс?

По теме - очередь сообщений ООООЧень быстрая. Задержки в ней не замечается и не заметите, разве что слипать будете поток(или спамить).

К тому же чего вы хотите добиться? Мгновенной передачи сообщения? Так возьмите и создаёте отдельный объект в потоке и спрячьте его. Пусть и крутит таймер.



Название: Re: Аналог виндового мультимедиа таймера в Qt
Отправлено: Alex_C от Июнь 21, 2012, 21:57
Да, я знаю, что для программиста, впервые столкнувшегося со столь специфическим таймером, это как откровение :)
Точность этого таймера по официальной информации не хуже 1мс. Да-да, везде пишут, что точность Виндовс - 15 мс. Но по ходу это не программый, а аппаратный таймер, входящий в состав материнской платы (не уверен - точной инфы по этому поводу не нашел)
Основная особенность этого таймера - при возникновении события он блокирует выполнение всех процессов в системе, и выполняет callback ф-цию. По этому никакими тредами его заменить нельзя - в них погрешность действительно 15 мс.
Зачем он нужен? Как видно из названия - для мультимедиа :)
У меня же он используется для управления внешним девайсом по ком-порту (выставлением высокого/низкого уровня по RTS-DTR). При использовании виндового таймера, тредов происходит сбой посылок, что не дает возможности управлять устройством.


Название: Re: Аналог виндового мультимедиа таймера в Qt
Отправлено: Bepec от Июнь 21, 2012, 22:03
Я тебе по секрету сообщу ) Это такой же таймер, базирующийся на кварце :D Просто вместо постановки события в очередь, он вызывает исполнение события :D

postEvent sendEvent что нить говорят?:)

Погрешность у него такая же ) +-15мс.

И опять по секрету скажу - Qt использует его, насколько я понимаю :D Обычный QTimer вызывает платформозависимый код, который в свою очередь вызывает что? Один из таймеров виндовс.
В моём проекте достигается точность в 1-2мс, с периодическими прорывами в 13-14 мс. И это норма.

PS Прочитал 3 статьи, перерыл исходники Qt :D


Название: Re: Аналог виндового мультимедиа таймера в Qt
Отправлено: Alex_C от Июнь 21, 2012, 22:19
Да прийдется смотреть исходники QTimer. Какой таймер используется там.
На счет postEvent sendEvent все понятно... Но добиться эффекта без использования мультимедиа таймера под виндой с заданной точностью не получается.


Название: Re: Аналог виндового мультимедиа таймера в Qt
Отправлено: Bepec от Июнь 21, 2012, 22:33
значит используй его :D Qt в любом случае использует платформозависимый код :)


Название: Re: Аналог виндового мультимедиа таймера в Qt
Отправлено: Alex_C от Июнь 21, 2012, 22:43
К сожалению под виндой QTimer использует стандартный виндовый таймер, что не дает нужной точности.
Прийдется писать свой аналог QTimer, где под виндой использовать мультимедиа таймер, а под Линуксом - уже нашел - есть аналог мультимедийного таймера. В принципе код получится простой :)

P.S. Хорошо что под Mac пока делать не надо!


Название: Re: Аналог виндового мультимедиа таймера в Qt
Отправлено: Alex_C от Июнь 21, 2012, 22:50
Ура-ура!
Нашел ответ на свой вопрос! Все же не устаю удивляться, как все продуманно в Qt!
Оказывается, при задании интервала менее 20 мс, под виндой используется мультимедиа таймер, при большем интервале - стандартный виндовый. Во как!!!

http://www.qtcentre.org/threads/27328-QTimer-resolution


Название: Re: Аналог виндового мультимедиа таймера в Qt
Отправлено: Bepec от Июнь 21, 2012, 23:10
Я ж и говорю. точность 1-2 мс у мну в проекте ) всё круто :D


Название: Re: Аналог виндового мультимедиа таймера в Qt
Отправлено: Alex Custov от Июнь 25, 2012, 13:48
а под Линуксом - уже нашел - есть аналог мультимедийного таймера.

Скинь ссылку


Название: Re: Аналог виндового мультимедиа таймера в Qt
Отправлено: Bepec от Июнь 25, 2012, 13:52
Alex Custov - Есть такое подозрение, что тролли и об линуксовском таймере подумали. Во всяком случае на линуксе моя программа выдаёт ту же погрешность 1-2 мс. Меньше уже просто нереально :D


Название: Re: Аналог виндового мультимедиа таймера в Qt
Отправлено: xokc от Июнь 25, 2012, 23:48
Оказывается, при задании интервала менее 20 мс, под виндой используется мультимедиа таймер, при большем интервале - стандартный виндовый. Во как!!!
http://www.qtcentre.org/threads/27328-QTimer-resolution
Не очень убедительно. Если поглазеть на исходники, никакого multimedia timer не используется. Используется процессорный Performance Counter, но это уже совсем другая история. Забудьте навсегда словосочетания Windows и 1 мс. Любой из таймеров в виндовс в общем случае гарантированно не будет срабатывать ни за какой промежуток времени - ОС не рассчитана реалтайм применение. Если процессор будет загружен чем-то с его точки зрения более важным, Ваш таймер может не сработать никогда, независимо от способа его реализации, будь то GetTickCount (стандартный таймер Windows), timeGetTime (multimedia timer) или QueryPerformanceFrequency (Performance Counter). Про Линукс говорить не буду - нет большого опыта программирования под него, но что-то мне подсказывает, что там ситуация похожая.


Название: Re: Аналог виндового мультимедиа таймера в Qt
Отправлено: Alex Custov от Июнь 26, 2012, 01:14
Во всяком случае на линуксе моя программа выдаёт ту же погрешность 1-2 мс. Меньше уже просто нереально :D

Скинь минимальный тестовый пример.


Название: Re: Аналог виндового мультимедиа таймера в Qt
Отправлено: Bepec от Июнь 26, 2012, 07:19
Увы, не получится. Там практически всё построено на корпоративных классах :) За разглашение - наказывается лишением свободы на срок от трех до семи лет. :D

Что могу сказать без примера:

Хокс во первых прав (погрешность та же в 1-15 мс остаётся), это уже виндосовские заморочки.
Во вторых погрешность почему-то отрабатывает раз в какой-то промежуток времени.
Т.е. к примеру 15 сигналов с перерывом в 1-2 мс (), далее неизвестный тормоз на 2-15 мс и продолжаемс..

PS Хотя у меня один знакомый пытался собрать модель для тактового подсчёта, но не смог :)


Название: Re: Аналог виндового мультимедиа таймера в Qt
Отправлено: xokc от Июнь 26, 2012, 08:46
Во вторых погрешность почему-то отрабатывает раз в какой-то промежуток времени.
Т.е. к примеру 15 сигналов с перерывом в 1-2 мс (), далее неизвестный тормоз на 2-15 мс и продолжаемс..
Так и я об этом же. Установите интервал таймера, например, в 10 мс, и посчитайте количество срабатываний за продолжительный промежуток, например за 10 мин, и увидите, что если в это время комп занимается обычными делами (переключает задачи, качает файлы и т.п.), то:
1. Количество срабатываний не будет равно 10 * 60 * 1000 / 10.
2. Интервал между срабатываниями будет самый разный, вплоть до сотен милисекунд.
Ни один из видов системных таймеров не даст на ОС, не имеющей realtime подсистемы стабильных срабатываний с малыми интервалами. Как один из вариантов выхода из этой ситуации - учитывать время срабатывания таймера и вызывать обработчик таймера столько раз, сколько "лишних" тиков уже накопилось. Например, если нужен интервал в 10 мс, а с момента последнего срабатывания прошло 22 мс, то вызывать обработчик 2 раза и запомнить, что 2 мс ещё осталось и их тоже надо учесть при следующем вызове.


Название: Re: Аналог виндового мультимедиа таймера в Qt
Отправлено: Bepec от Июнь 26, 2012, 09:31
Кхм. Хокс вы неправы.

Количество срабатываний будет меньше, но максимальная погрешность - 15 мс минус железо компьютера.

Причём, если вы незнаете, виндосовский таймер как раз и базируется на МК. Точное её название не упомню, но она осталась с далёких времён.

И да, Ваш "вариант выхода" несовершенен по 1 простой причине - время прошедших секунд, считает ТОТ ЖЕ САМЫЙ таймер. И ЛЮБОЙ таймер на виндовсе основывается на том самом МК :) Завязано всё на него, увы.

PS да, до сотен тактов в мс в Windows не добиться. Но оно там и нафиг ненужно. Для пользователя 25 мс - ничто. Для программиста это - почти вечность :)

Хотите считать до 10000 тактов в секунду - программируйте на МК :)


Название: Re: Аналог виндового мультимедиа таймера в Qt
Отправлено: xokc от Июнь 26, 2012, 09:50
Причём, если вы незнаете, виндосовский таймер как раз и базируется на МК. Точное её название не упомню, но она осталась с далёких времён.
Не очень понимаю, что тут имеется в виду под МК - микроконтроллер?

И да, Ваш "вариант выхода" несовершенен по 1 простой причине - время прошедших секунд, считает ТОТ ЖЕ САМЫЙ таймер. И ЛЮБОЙ таймер на виндовсе основывается на том самом МК :) Завязано всё на него, увы.
Ну всё же не совсем так. В качестве исходного генератора для мультимедиа таймера используется кварц, находящийся в звуковой плате. Он, в зависимости от её производителя, может быть как хуже, так и лучше по точности, чем кварц материнской платы. Кроме того, измерение времени через QueryPerformanceCounter существенно точнее, и чем GetTickCount Windows, и чем timeGetTime - MSDN об этом говорит следующее: The default precision of the timeGetTime function can be five milliseconds or more, depending on the machine. ... Use the QueryPerformanceCounter and QueryPerformanceFrequency functions to measure short time intervals at a high resolution.

PS да, до сотен тактов в мс в Windows не добиться. Но оно там и нафиг ненужно. Для пользователя 25 мс - ничто. Для программиста это - почти вечность :)
Хотите считать до 10000 тактов в секунду - программируйте на МК :)
Не вижу, где я утверждал бы обратное.


Название: Re: Аналог виндового мультимедиа таймера в Qt
Отправлено: Bepec от Июнь 26, 2012, 10:39
Мультимедия и обычные таймеры базируются на одном и том же Микроконтроллере - часах реального времени. Разница только в реализации - обычный таймер менее требователен к ресурсам, но неточен. Мультимедия же точнее, но время на его исполнение больше.

Кьюред - сам определяет с помощью какого устройства лучше генерировать тики. Но в любом случае будет погрешность :D  Опять таки 15мс - железо машины.

Цитировать
По-прежнему частота импульсов на выходе нулевого канала таймера равна приблизительно 18.2 герц (в зависимости от комплектации компьютера)
Это цитата Микрософта. Именно эта константа не даст тебе и мне,  и кому-либо другому подсчитать время точнее. Повысить частоту можно - достаточно спаять свою материнку :D

Есть выход - собственный таймер, собственное устройство, подключаемое к PCI/USB и собственная ОС реального времени :D

Иначе - увы.


Название: Re: Аналог виндового мультимедиа таймера в Qt
Отправлено: Igors от Июнь 26, 2012, 10:53
Как один из вариантов выхода из этой ситуации - учитывать время срабатывания таймера и вызывать обработчик таймера столько раз, сколько "лишних" тиков уже накопилось. Например, если нужен интервал в 10 мс, а с момента последнего срабатывания прошло 22 мс, то вызывать обработчик 2 раза и запомнить, что 2 мс ещё осталось и их тоже надо учесть при следующем вызове.
Я пользуюсь примерно таким же способом, и это работает хорошо. Псевдокод
Код
C++ (Qt)
void MyTimerProc( void )
{
int numFramesNeed = (currentTime() - startTime) / frameTime;  // сколько кадров должно быть показано
if (numFramesNeed > numFramesDone) {  // если больше чем сделано - показываем следующий
 ++numFramesDone;
 ShowFrame();
}
}
 
При этом интервал таймера просто в 2 раза меньше frameTime, ну можно в 3 или 4 если хочется большей точности. А изучение подробностей/потрохов ОС утомляет без всякой выгоды  :) 


Название: Re: Аналог виндового мультимедиа таймера в Qt
Отправлено: Bepec от Июнь 26, 2012, 10:56
Igors - и какой точности удаётся добиться? Частота обновления то какая?

PS и насколько я понимаю, вы совершаете 2 вызова подряд, если время прошло для 2 вызовов? Тогда смысл в первом вызове для его последующей замены мгновенно вторым?


Название: Re: Аналог виндового мультимедиа таймера в Qt
Отправлено: Igors от Июнь 26, 2012, 11:04
Igors - и какой точности удаётся добиться? Частота обновления то какая?

PS и насколько я понимаю, вы совершаете 2 вызова подряд, если время прошло для 2 вызовов? Тогда смысл в первом вызове для его последующей замены мгновенно вторым?
Наоборот, "не мгновенно". Кадоы показываются с большей частотой если время "убежало вперед". Интервал между ними меньше но не ноль - иначе глаз опознает "разрыв" 


Название: Re: Аналог виндового мультимедиа таймера в Qt
Отправлено: Alex Custov от Июнь 26, 2012, 11:34
Хокс во первых прав (погрешность та же в 1-15 мс остаётся), это уже виндосовские заморочки.
Во вторых погрешность почему-то отрабатывает раз в какой-то промежуток времени.
Т.е. к примеру 15 сигналов с перерывом в 1-2 мс (), далее неизвестный тормоз на 2-15 мс и продолжаемс..

Ну так это, как уже объяснили, никакой гарантии не даёт и не может дать. твоя задача висела в foreground и успевала отработать несколько таймеров, потом когда планировщик её скинул, интервалы исполнения таймеров существенно увеличились.


Название: Re: Аналог виндового мультимедиа таймера в Qt
Отправлено: Alex Custov от Июнь 26, 2012, 11:40
Есть выход - собственный таймер, собственное устройство, подключаемое к PCI/USB и собственная ОС реального времени :D

Иначе - увы.

А зачем всё собственное, уже давно всё придумано. К тому же, скажем так, это будет трудно сделать в userspace. В Linux на уровне ядра, например, есть значительно более точные таймеры, чем 15 мс.


Название: Re: Аналог виндового мультимедиа таймера в Qt
Отправлено: Bepec от Июнь 26, 2012, 11:54
Линукс и виндовс это ... Не буду объяснять что это :)

Гарантии дать не может, но для пользователя 15-20 мс роли не играют. Ни в чём. Даже если и будет разрыв, мозг его достроит :)

Точнее не, не так. Гарантия ЕСТЬ и БУДЕТ, что разрыв будет максимум 15 мс.

Кстати разрыв таймера и отсчёта времени = есмь одно и то же.

Отсчёт времени - такой же таймер. С такой же погрешностью. И даже если опять набегут критики -переключение между потоками (выделение процессорного времени) ТОЖЕ использует тот же таймер. С такой же погрешностью. Микрософтовцы правда пытаются убрать эту зависимость, но пока тщётно.

Проще выражаясь - как вы не будете мудрить, как вы не будете писать приложение, в виндовсе потоки вашего приложения могут быть спокойно "заморожены" на время этой погрешности.

просто прикол:
Был где то клип, где показывались разные фигуры в движении с разрывами в 20-30 мс. Мозг автоматом достраивает картинку. А вот перематываешь ручками - оппа нету ничего :D


Название: Re: Аналог виндового мультимедиа таймера в Qt
Отправлено: Alex Custov от Июнь 26, 2012, 12:17
Отсчёт времени - такой же таймер. С такой же погрешностью. И даже если опять набегут критики -переключение между потоками (выделение процессорного времени) ТОЖЕ использует тот же таймер. С такой же погрешностью.

Не с такой же. Интервалы в Linux отсчитываются относительно счётчика jiffies, который зависит от вкомпилированного значения HZ, от 100 до 1000. Это значение может использоваться для перепрограммирования аппаратного таймера до более точного значения, чем 18 Hz, а значит, что на задачу может быть использовано вплоть до 1 мс. Опять же, на уровне ядра.

Микрософтовцы правда пытаются убрать эту зависимость, но пока тщётно.

Каким образом, интересно? Созданием нового чипа для плат?


Название: Re: Аналог виндового мультимедиа таймера в Qt
Отправлено: Bepec от Июнь 26, 2012, 12:30
Во первых - пытаются отказаться от этого чипа.

Во вторых я обсуждаю Windows, а не Linux. Имеете глаза - читайте.
 
PS я могу на своём домашнем ардуино сверхточные прошивки бацать, но простите уж, 98% пользователей на винде.

PPS официальную статистику не смотрите - туда входят только ОФИЦИАЛЬНЫЕ продажи Microsoft "D


Название: Re: Аналог виндового мультимедиа таймера в Qt
Отправлено: Alex Custov от Июнь 26, 2012, 14:02
Во первых - пытаются отказаться от этого чипа.

В пользу чего?

Во вторых я обсуждаю Windows, а не Linux. Имеете глаза - читайте.

Не знаю что ты обсуждаешь, т.к. ты написал "Линукс и виндовс это ... Не буду объяснять что это", что это значит понятно только тебе, поэтому ниоткуда не следует что ты обсуждаешь исключительно Windows. Тема изначально нацелена на кроссплатформенность, а не Windows.


Название: Re: Аналог виндового мультимедиа таймера в Qt
Отправлено: Bepec от Июнь 26, 2012, 14:14
Насчёт линукса и виндовса - это холивар. Бессмысленный и беспощадный. Яблоко с чернозёмом мешают.

Насчёт о кроссплатформенности - почитай 1 пост и поймёшь, что речь идёт о Мультимедиа таймере, который используется только в Windows и спрашивается о "кроссплатформенности" аналога для использования в Windows. Ибо это Windooows :D
Не можешь уследить за ходом разговора - извиняюсь тогда, но стоит ли лезть туда, за чем уследить не можешь? :D

В пользу чего отказываются - неясно. И не узнаем скорее всего до тех пор, пока не обнародуют решение. Обычные заявления Микрософта - мы откажемся, но вот как - узнаете когда выпустим :D


Название: Re: Аналог виндового мультимедиа таймера в Qt
Отправлено: Alex Custov от Июнь 26, 2012, 15:53
Насчёт о кроссплатформенности - почитай 1 пост и поймёшь, что речь идёт о Мультимедиа таймере, который используется только в Windows и спрашивается о "кроссплатформенности" аналога для использования в Windows. Ибо это Windooows :D

Автор сказал, что не хочет писать платформозависимый код, и далее уже нашёл какой-то код для быстрого таймера в Linux, и что хорошо, что пока под Мак не требуется портировать. Если у кого-то проблемы с восприятием текста, так это у тебя. Винду он просто привёл в пример.


Название: Re: Аналог виндового мультимедиа таймера в Qt
Отправлено: Bepec от Июнь 26, 2012, 17:12
Как известно , в винде есть так называемый мультимедиа таймер, отличие от простого таймера в том, что он выполняется в четко заданные промежутки времени , а не когда освободится система, как в обычном таймере, и в том, что вызываемая в нем callback-функция вызывается в отдельном потоке. Вопрос - понятно что под Qt можно использовать непосредственно сам мультимедиа таймер, но но это получается платформазависимый код. А как реализовать мультимедиа таймер средствами Qt?

Поясняю специально для Густава. Вольный перевод начала темы:

Есть в ОС WINDOWS таймер, который меня устраивает. Его я могу использовать напрямую через WinApi в ОС WINDOWS. Как реализовать аналог Multimedia таймер средствами Qt.

В дальнейшем, он нашёл решение под Linux и вопрос темы перешёл на одну ОС - WINDOWS.

В дальнейшем же, он узнал, что ему нет необходимости утруждать себя - в Qt предусмотрено его использование, в ОС WINDOWS.

Тема уже закрыта, а вы, простите уж, собачитесь тут :)


Название: Re: Аналог виндового мультимедиа таймера в Qt
Отправлено: Alex Custov от Июнь 26, 2012, 19:13
Поясняю специально для Густава. Вольный перевод начала темы:

Специально для слепых повторяю второй раз - прочитай внимательно мой ник или настрой шрифты в браузере.

И опять же процитирую:

Цитировать
Прийдется писать свой аналог QTimer, где под виндой использовать мультимедиа таймер, а под Линуксом - уже нашел - есть аналог мультимедийного таймера

Цитировать
P.S. Хорошо что под Mac пока делать не надо

Речь идёт о кроссплатформенном таймере, что там у тебя пошло "потом" я не знаю, как и исходников я не видел, как и заявление о переключении "потоков" было сделано без контекста винды. А я веду речь в русле темы, а не твоего потока сознания по поводу каких-то тюремных заключений и смайликов.


Название: Re: Аналог виндового мультимедиа таймера в Qt
Отправлено: Bepec от Июнь 26, 2012, 19:55
Тьфу. Пиши что хочешь, вопрос темы решён, а ты собачишься. Удачно похоливарить :)