Комментарии 65
Почему не QueryPerformanceCounter()?
Beware of QueryPerformanceCounter()
www.virtualdub.org/blog/pivot/entry.php?id=106
www.virtualdub.org/blog/pivot/entry.php?id=106
QueryPerformanceCounter counts elapsed time, not CPU cycles
blogs.msdn.com/oldnewthing/archive/2008/09/08/8931563.aspx
blogs.msdn.com/oldnewthing/archive/2008/09/08/8931563.aspx
На мой взгляд, само получение значения tsc затратит меньше процессорных тактов и данные получатся точнее (как вместо sleep я использовал NtDelayExecution. Еще мелочь, но QueryPerformanceCounter возвратил мне 0 на системе PIII с win2k, а tsc — нормальное значение.
Хотя, я не против, конечно QueryPerformanceCounter, QueryPerformanceFrequency также вполне можно использовать.
Я еще поэкспериментирую с применением этих функций.
Хотя, я не против, конечно QueryPerformanceCounter, QueryPerformanceFrequency также вполне можно использовать.
Я еще поэкспериментирую с применением этих функций.
пока у вашей операционной системы не появится real-time scheduler говорить о каких бы то ни было точных измерениях времени бесполезно… thread/process switch отжирает драгоценное время, обработка прерываний происходит в ущерб программам уровня пользователя. опираться на полученные результаты нет смысла. единственное, что гарантируют все эти функции — процесс проспит не меньше указанного интервала времени. под различной нагрузкой в реальных приложениях все это треснет по швам к сожалению
Дополнительная информация:
1. На некоторых процессорах значение RDTSC может быть рассинхронизировано для разных ядер. Вы никогда не знаете, на каком именно ядре в данный момент выполняется Ваша программа (если только не выставили affinity mask, да и то, я бы не был на 100% уверен), поэтому чтение TSC процессорной командой иногда само вносит существенные искажения. В SMP системах RDTSC вообще по определению рассинхронизировано между процессорами. Поэтому думаю, что performance counters лучший метод для точных замеров времени в прикладных программах для Windows.
2. Программу для Windows не стоит писать так, чтобы она зависела от задержек в функциях типа Sleep. Если речь идет об управлении устройством в реальном времени, то нужно выносить все это в драйвер. В других случаях использовать мультимедийные функции для таймирования. А если кто-то пишет часы для desktop-а – вероятно лучше всего подойдут waitable timers.
1. На некоторых процессорах значение RDTSC может быть рассинхронизировано для разных ядер. Вы никогда не знаете, на каком именно ядре в данный момент выполняется Ваша программа (если только не выставили affinity mask, да и то, я бы не был на 100% уверен), поэтому чтение TSC процессорной командой иногда само вносит существенные искажения. В SMP системах RDTSC вообще по определению рассинхронизировано между процессорами. Поэтому думаю, что performance counters лучший метод для точных замеров времени в прикладных программах для Windows.
2. Программу для Windows не стоит писать так, чтобы она зависела от задержек в функциях типа Sleep. Если речь идет об управлении устройством в реальном времени, то нужно выносить все это в драйвер. В других случаях использовать мультимедийные функции для таймирования. А если кто-то пишет часы для desktop-а – вероятно лучше всего подойдут waitable timers.
Используя для оптимизации кода профайлер из состава библиотеки Jedi, позволил себе исследовать его с целью определения не только общего времени выполнения блока кода, количества запусков и, соответственно, среднего времени операции, но и максимального времени выполнения одиночной операции. Обнаружилось нечто интересное — для блоков кода со средним временем выполнения менее 1 мс значение максимального времени давало часто 16 мс, а то и 32. Особенно когда общее время выполнения при сотнях и тысячах запусков как раз получается те же 16 или 32 мс.
В том профайлере для замера временных отсечек используется функция GetTickCount. Не подскажете, чем заменить ее для более точного отсчета малых интервалов?
В том профайлере для замера временных отсечек используется функция GetTickCount. Не подскажете, чем заменить ее для более точного отсчета малых интервалов?
denim, все так, но описанное хотя бы чуть-чуть поднимает и пробует решить проблему…
sysprg, к сожалению не было возможности проверить и убедиться в преимуществах QueryPerformanceCounter на многоядерных системах, но судя по сказанному Вами, его действительно лучше использовать. Прежде всего я искал способ получить задержки, и для эксперимента, в котором RDTSC служил для подсчета, он пока мне сгодился.
А задержки эти, увы с нужным интервалом не получил: тоже верно — нужен драйвер. Хотя если задержки до 1 мс, можно обойтись, как я описал (NtDelayExecution, sleep, таймеры).
sysprg, к сожалению не было возможности проверить и убедиться в преимуществах QueryPerformanceCounter на многоядерных системах, но судя по сказанному Вами, его действительно лучше использовать. Прежде всего я искал способ получить задержки, и для эксперимента, в котором RDTSC служил для подсчета, он пока мне сгодился.
А задержки эти, увы с нужным интервалом не получил: тоже верно — нужен драйвер. Хотя если задержки до 1 мс, можно обойтись, как я описал (NtDelayExecution, sleep, таймеры).
Даже если выставить real-time приоритет для thread, то все равно из-за подкачки/откачки страниц или еще каких-то влияний ядро Windows не всегда мгновенно активирует пользовательскую программу, поэтому писать на прикладном уровне для Windows что-то зависящее от задержек в 1 миллисекунду и меньше — вообще неправильно и малореально. Как и для Linux. С такими вещами нужно или на уровне ядра работать, или использовать специализированные системы реального времени. Как минимум в Windows или в Linux нужно выключать своппинг и не запускать в параллель всякие мультимедийные программы. Но это уже превращает программу в пригодную к использованию только на выделенной машине. Вывод — не очень подходят ОС общего назначения для этого, на прикладном уровне…
В любом случае спасибо за интересную статью! Можно убрать накопление погрешности, это да. Но нельзя обеспечить четкую активацию в точное время с точностью до миллисекунд. Если Вы запустите Ваши программы с любым методом точных задержек параллельно с какой-нибудь ресурсо-жрущей игрушкой, то Вы увидите, что какой бы Вы не использовали метод задержки и какой бы приоритет для thread не выбрали, но время от времени будут происходить задержки в активации thread более чем на одну миллисекунду из-за свопинга или из-за того, что некоторые directx операции не прерываются ядром, и обеспечить мгновенную активацию прикладной программы для Windows в суб-миллисекундном диапазоне в общем случае невозможно.
Очень интересное исследование, спасибо! Срочно ищу по всем юнитам проекта, не используются ли где-либо малые задержки…
профилирование программ
Далеко не все промышленные системы являются «тру» real-time.
Однако сертификацию им проходить все равно требуется.
И это лишь один из примеров.
Однако сертификацию им проходить все равно требуется.
И это лишь один из примеров.
В большинстве штатных ситуаций они, все-таки, предсказуемы.
Другое дело, что гарантий никаких нет 8)
Другое дело, что гарантий никаких нет 8)
Это вы несколько путаете — теорию и реальную жизнь.
При бюджете, например, в 50 тысяч никто не будет вам разрабатывать систему реального времени, снимающую показания с измерительных приборов и отражающих их на индикаторах, за которыми наблюдает диспетчер. Есть ГОСТы, регламентирующие время от изменения показателя до отражения этого изменения, и программа(к слову, написанная на Delphi) с этим справляется — за несколько лет никаких проблем. Это я и называю «предсказуемость в штатной ситуации» — если система даже не real-time, то можно увеличить ее предсказуемость, снижая количество влияющих на нее факторов.
Можно сколько угодно пыжиться и надувать щеки в стиле «а вот если вдруг...», «гарантий нет, что ....» — факт в том, что есть решение, устраивающее заказчика(и реально работающее), и по устраивающей разработчика стоимости.
При бюджете, например, в 50 тысяч никто не будет вам разрабатывать систему реального времени, снимающую показания с измерительных приборов и отражающих их на индикаторах, за которыми наблюдает диспетчер. Есть ГОСТы, регламентирующие время от изменения показателя до отражения этого изменения, и программа(к слову, написанная на Delphi) с этим справляется — за несколько лет никаких проблем. Это я и называю «предсказуемость в штатной ситуации» — если система даже не real-time, то можно увеличить ее предсказуемость, снижая количество влияющих на нее факторов.
Можно сколько угодно пыжиться и надувать щеки в стиле «а вот если вдруг...», «гарантий нет, что ....» — факт в том, что есть решение, устраивающее заказчика(и реально работающее), и по устраивающей разработчика стоимости.
1. Его(измерения) появление в БД
2. Его появление на индикаторе, на который смотрит диспетчер
2. Его появление на индикаторе, на который смотрит диспетчер
1. Ну, БД бывают разные. В данном случае, их несколько, но в данном случае важна лишь одна — ин-мемори, без транзакций. Часть данных являются «высокоприоритетными» — при заполнении их определенными значениями, срабатывают определенные алгоритмы обратной связи(грубо говоря — скакнул ток — сработала защита).
2. Странно, да. Но при сертификации этот фактор не учитывают. Есть отраслевые требования, задокументированные приказом таким-то, хотите получить сертификат — демонстрируйте соответствие.
2. Странно, да. Но при сертификации этот фактор не учитывают. Есть отраслевые требования, задокументированные приказом таким-то, хотите получить сертификат — демонстрируйте соответствие.
Многовато вопросов задаете, мы уже в сторону ушли 8)
Отвечаю: до индикации время измеряется другой софтиной — эмулятором индикатора, где записываются временные метки значений. Потом достаточно сравнить их с теми, что приходят со счетчика. Ну а время синхронизируется с GPS-приемником.
Неточностей в связи со всем этим — море. Когда я ковырялся с GPS, вскрылись такие бездны «гуляния» системного таймера виндов, что хватались за голову — для обычного процесса там и речи нет даже о точности более чем в 0.1 с. При помощи таких вот статей все эти неточности можно несколько уменьшить. И иногда и это «несколько» может хорошо выручить — будь подобная(только более развернутая и с рассмотрением других вариантов) статья у меня под рукой пару-тройку лет назад — здорово бы сэкономил свое время. Умный, как известно, предпочитает учиться на чужих ошибках.
Real-time систему не на спецжелезе со спецосью не построишь, это факт. Но далеко не всегда требуется настоящий real-time.
Отвечаю: до индикации время измеряется другой софтиной — эмулятором индикатора, где записываются временные метки значений. Потом достаточно сравнить их с теми, что приходят со счетчика. Ну а время синхронизируется с GPS-приемником.
Неточностей в связи со всем этим — море. Когда я ковырялся с GPS, вскрылись такие бездны «гуляния» системного таймера виндов, что хватались за голову — для обычного процесса там и речи нет даже о точности более чем в 0.1 с. При помощи таких вот статей все эти неточности можно несколько уменьшить. И иногда и это «несколько» может хорошо выручить — будь подобная(только более развернутая и с рассмотрением других вариантов) статья у меня под рукой пару-тройку лет назад — здорово бы сэкономил свое время. Умный, как известно, предпочитает учиться на чужих ошибках.
Real-time систему не на спецжелезе со спецосью не построишь, это факт. Но далеко не всегда требуется настоящий real-time.
Ну, архитектуру мудрил не я. Разработчикам далеко не всегда дают требуемые сроки и возможность делать «как надо бы по-хорошему», вы не знали? 8)
Я еще раз говорю — вы слишком привязаны к теории. В жизни оно по-разному складывается.
>В чем проблема? Запросто!
AVR-ка, мигающая светодиодами? 8))
Проблем разных много, их сложно охватить в рамках дискуссии в комментариях, да и не силен я в матчасти.
Я еще раз говорю — вы слишком привязаны к теории. В жизни оно по-разному складывается.
>В чем проблема? Запросто!
AVR-ка, мигающая светодиодами? 8))
Проблем разных много, их сложно охватить в рамках дискуссии в комментариях, да и не силен я в матчасти.
>Видел ПО
Я сам писал — чувствуете разницу?
>для управление производственной линией под DOS/4GW
DOS тоже отвечает не всем требованям стандартов Real-time ОС. Геморы с драйверами, отсутствие многозадачности, как следствие — отсутствие вменяемого IPC.
Я сам писал — чувствуете разницу?
>для управление производственной линией под DOS/4GW
DOS тоже отвечает не всем требованям стандартов Real-time ОС. Геморы с драйверами, отсутствие многозадачности, как следствие — отсутствие вменяемого IPC.
Главное требование для hard real-time — гарантированный результат операции за четко определенный промежуток времени. DOS этого не гарантирует.
С каких это пор там что-то гарантировано?
А если, например, возникнет прерывание?
Или CLI и побежали? Далеко не убежите 8)
А если, например, возникнет прерывание?
Или CLI и побежали? Далеко не убежите 8)
По-моему, вы несколько заблуждаетесь относительно DOS'а.
Ну на этом тогда и закончим.
С вопросами веры — это к батюшкам в церковь 8)
С вопросами веры — это к батюшкам в церковь 8)
Во-первых, RTKernel по сути практически заменяет DOS(чего разработчики и не отрицают, допуская установку на комп вообще без оси).
Во-вторых, я же вроде изначально говорил о том, что реальная жизнь вносит коррективы. RTKernel, например, сам по себе стоит 1000 евро. А где вы найдете под него разработчика, если речь не про Москву? Сколько такой разработчик запросит денег? А как вы будете поддерживать свой продукт? А если требуется возможность багфикса через интернет?
В-третьих, даже с RTKernel вы получаете soft real-time, а никак не hard real-time. Т.е. от простой программы под Windows оно будет отличаться только тем, что тайминги будут намного(но все же не бесконечно много) надежнее. Гарантии все равно не будет.
Во-вторых, я же вроде изначально говорил о том, что реальная жизнь вносит коррективы. RTKernel, например, сам по себе стоит 1000 евро. А где вы найдете под него разработчика, если речь не про Москву? Сколько такой разработчик запросит денег? А как вы будете поддерживать свой продукт? А если требуется возможность багфикса через интернет?
В-третьих, даже с RTKernel вы получаете soft real-time, а никак не hard real-time. Т.е. от простой программы под Windows оно будет отличаться только тем, что тайминги будут намного(но все же не бесконечно много) надежнее. Гарантии все равно не будет.
>Это не противоречит ни одной моей фразе, сказанной выше.
Ну, например, он не совсем «поверх» DOS 8)
Да и речь вроде шла на основе DOS'а а не спецсофте — в самом начале ветки я и писал, что спецжелезо и спецсофт требуются для Hard real-time.
Кроме того, я не спец в архитектуре x86, вполне возможно, что и там есть затыки.
>Это уже другой вопрос, не связанный с «можно ли для DOS сделать realtime-приложение»
Не забывайте, что речь началась с вашего вопроса «для чего это нужно». Я объяснил, что soft real-time системы можно строить и на бытовых осях, при определенном подходе.
Ну чего вы реально под DOS навертите(при разумных затратах), если, например, вам обрабатывать надо гигабайты данных в час, где-то их складировать, куда-то их пересылатьи т.п.? Десятком/сотней станков порулить — это одно, а вот тысячей управляемых источников данных?
>Ниже некуда.
А драйвера? А обработчики прерываний?
Дискуссия, по-моему, переходит в затяжную. Если у вас есть аккаунт в Wave-предлагаю обсудить там. Если нет, могу прислать инвайт — пишите почту в личку.
Ну, например, он не совсем «поверх» DOS 8)
Да и речь вроде шла на основе DOS'а а не спецсофте — в самом начале ветки я и писал, что спецжелезо и спецсофт требуются для Hard real-time.
Кроме того, я не спец в архитектуре x86, вполне возможно, что и там есть затыки.
>Это уже другой вопрос, не связанный с «можно ли для DOS сделать realtime-приложение»
Не забывайте, что речь началась с вашего вопроса «для чего это нужно». Я объяснил, что soft real-time системы можно строить и на бытовых осях, при определенном подходе.
Ну чего вы реально под DOS навертите(при разумных затратах), если, например, вам обрабатывать надо гигабайты данных в час, где-то их складировать, куда-то их пересылатьи т.п.? Десятком/сотней станков порулить — это одно, а вот тысячей управляемых источников данных?
>Ниже некуда.
А драйвера? А обработчики прерываний?
Дискуссия, по-моему, переходит в затяжную. Если у вас есть аккаунт в Wave-предлагаю обсудить там. Если нет, могу прислать инвайт — пишите почту в личку.
P.S. минусы вам проставляю не я, это кто-то набежал со стороны в нашу ветку 8(
Делфи… как давно это было…
Отвык уже от begin-end…
Отвык уже от begin-end…
Интересно, насколько он еще используется в реальных проектах?..
Довольно часто. По ссылке показаны примеры популярных программ, написанных на Delphi: www.embarcadero.com/application-showcase
Исчезающе мало.
Смотрим статистику вакансий на Dice.com:
C# — 4800
Java — 10086
Delphi — 53
Смотрим статистику вакансий на Dice.com:
C# — 4800
Java — 10086
Delphi — 53
Методология измерения не совсем правильная. NtDelayExecution переносит поток из списка плнируемых в список ожидания. Повторный запуск произойдет через заданный интервал + время до следующего планирования + время на смену контектов потока. Поэтому маленькие интервалы никогда не будут правильно измеряны в ОС с планировщиками общего назначения. А при больших интервалах кажущаяся точность появляется потому, что отношение необходимой задержки к накладным расходам становится больше — накладные расходы меньше влияют на результат измерения. При переключении задач может также происходить инвалидация кеша процессора, его заполнение требует время, вероятность велика, если код долго не получал управления из-за того, что был отложен — скорее всего неиспользуемый код был вытеснен.
rdtsc также не является реальным показателем, как уже говорили про разные ядра и процессоры также стоит отнести регуляцию частоты в мобильных решениях. Также, с появлением переупорядочивания на конвеере в процессорах Интел не гарантируется, что rdtsc исполнится не раньше, чем предшествующие инструкции.
Таким образом, чтобы точно измерить интервал, надо не выходить в ожидание, а наоборот занять процессор полностью, время от врмени получая метки времени, желательно как-то избегать переключения задач или учесть накладные расходы на переключение — для этого необходимо будет найти способ определения моментов переключения контекстов, Clerk на васме писал про некоторые фичи Windows, которые позволяют засечь момент переключения контекстов.
Также желательно инвалидировать кеши 1 уровня перед замерами и очищать конвеер (например дальним вызовом, только тут может помешать предсказание переходов...).
rdtsc также не является реальным показателем, как уже говорили про разные ядра и процессоры также стоит отнести регуляцию частоты в мобильных решениях. Также, с появлением переупорядочивания на конвеере в процессорах Интел не гарантируется, что rdtsc исполнится не раньше, чем предшествующие инструкции.
Таким образом, чтобы точно измерить интервал, надо не выходить в ожидание, а наоборот занять процессор полностью, время от врмени получая метки времени, желательно как-то избегать переключения задач или учесть накладные расходы на переключение — для этого необходимо будет найти способ определения моментов переключения контекстов, Clerk на васме писал про некоторые фичи Windows, которые позволяют засечь момент переключения контекстов.
Также желательно инвалидировать кеши 1 уровня перед замерами и очищать конвеер (например дальним вызовом, только тут может помешать предсказание переходов...).
1. «На некоторых версиях Delphi есть готовая команда rdtsc»
Это не готовая команда на некоторых версиях Delphi, а наличие поддержки встроенным ассемблером оной команды. В Delphi6 уже есть, в старших тем более.
2. Про разные архитектуры процессоров, многоядерность и нереалтаймность Win32 уже сказали.
3. А какое практическое применение у этого метода? Т.е. когда он действительно дает принципиально лучший результат относительно известных стандартных? Ведь если мы имеем дело с получением некоторых отсчетов от некоторого железа, то удобнее всего (и так делается в реальной жизни) использовать метки времени от самого железа.
Это не готовая команда на некоторых версиях Delphi, а наличие поддержки встроенным ассемблером оной команды. В Delphi6 уже есть, в старших тем более.
2. Про разные архитектуры процессоров, многоядерность и нереалтаймность Win32 уже сказали.
3. А какое практическое применение у этого метода? Т.е. когда он действительно дает принципиально лучший результат относительно известных стандартных? Ведь если мы имеем дело с получением некоторых отсчетов от некоторого железа, то удобнее всего (и так делается в реальной жизни) использовать метки времени от самого железа.
Недавно нужна была подобная функциональность. За полчасика набросал базовый модуль для профайлинга, основываясь на QueryPerfomanceCounter. Получилась точность порядка 3 микросекунд (к сожалению, не помню, какой был процессор). Если бы использовать ассемблерные вставки, и дополнительные оптимизации, то, думаю, можно было бы догнать до 1 мкс (а может и еще точнее); но на тот момент мне данной точности было достаточно.
хороша статья) в мемориз)
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Точное время: измеряем, применяем