Перейти к содержанию
    

Максимальная возможная реалтаймовость под Win.

Вопрос несколько не по теме форума, но наверняка актуальный для многих при работе с железом из win-приложения.

Какова максимальная возможная реалтаймовость не-GUI потока win-приложения на уровне пользователя (без разработки драйвера уровня ядра)?

Допустим: Имеем отдельный поток (для работы с железом). Без GUI-вызовов из него. И без блокировок потока при доступе к разделяемым ресурсам (предположим - вся межпоточная синхронизация выполняется неблокирующими методами: Interlocked...()-функциями, межпоточными асинхронными сообщениями, сигналами и т.п.). Поток работает только со своими данными и своими же (выделенными только ему) ресурсами.

Так вот - как обеспечить максимально возможную реалтаймовость этого потока? Т.е. - чтобы все события в нём происходили максимально точно по заданными времянкам. Если скажем нужно, чтобы поток получал управление каждые 20 мсек, с минимальным отклонением от этого интервала вне зависимости от прочих событий в системе? Какими средствами этого достичь? На обычном ПК, без каких-то аппаратных добавлений к нему и без доп.драйверов на уровне ядра. На виндах от XP до последних.

 

Рабочему потоку (о котором и идёт речь) выставлен высокий приоритет = THREAD_PRIORITY_TIME_CRITICAL. Временные интервалы пробую создавать двумя методами:

1. Мультимедиа-таймером: timeBeginPeriod(1)/timeEndPeriod(1). Разрешение (запрошенное и выданное) = 1ms. Из callback-функции ММ-таймера пинаю рабочий поток посылкой ему сигналов (SetEvent()).

2. Созданием отдельного высокоприоритетного потока (также THREAD_PRIORITY_TIME_CRITICAL). Который занимается только тем, что ложится спать на 20 ms, просыпаясь посылает сигнал (SetEvent()) рабочему потоку и снова ложится спать. Больше ничего не делает.

Но оба этих метода работают не очень хорошо. :sad: Потестил программу в течение некоторого времени параллельно с обычной работой на двух разных ПК (ничего особенного - обычный набор программ: браузеры, компиляторы и т.п.) с разными win (Win7, Win11). Сделал сбор статистики периодичности вызовов функций пинания рабочего потока. Получаю такую картину:

image.thumb.png.6db9724d6f0aae878959411ffecdb874.png

С префикса "mmTimer" - статистика по вызовам мультимедиа-таймера. "Thread" - по вызовам из спец.потока. Статистика накоплена за время работы - немногим более часа.

3 столбца = минимальное/среднее/максимальное время между вызовами.

Как видно - разброс получился довольно значительный. Хоть ПК, на котором это работало - современный AMD Ryzen (6 ядер / 12 потоков) и не загружен особо. Почему так?  :umnik2:

Причём (как видно) - "Thread"-метод довольно хорошо держит нижнюю границу (отклонение менее 1 ms). Но зато - плохо держит верхнюю границу. Иногда возникают какие-то задержки аж на почти 70ms сверх положенного! Да и в среднем - отклонение больше, чем у ММ-таймера.

А мультимедиа-таймер лучше держит средний интервал, но очень плохо - нижний интервал (а это самый критичный для меня параметр). Причём - это в данном запуске теста нижний интервал упал всего до ~8.2 ms. В другом запуске на другом ПК он падал ещё ниже.

 

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

 

PS: Все данные измерений времени получены от службы аппаратного таймера - QueryPerformanceFrequency()/QueryPerformanceCounter(). Поэтому думаю - достоверны.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как-то очень давно в 7 или даже XP, опрашивал параллельным ещё портом какой-то микрометр с ~2кГц последовательным интерфейсом, через тупой опрос inp(), драйверами параллельного порта от avreal.

Путём спихивания процесса руками через SetProcessAffinityMask на какое-нибудь ядро с номером повыше, чтобы там ему никто не мешал, работало вполне стабильно, но какой там именно был джиттер не проверял. Без этого, просто изменением приоритета, было хуже.

Можно наверное ещё где-то шедулеру посоветовать определённые ядра не использовать другими процессами, чтобы там только он один крутился.

я бы вот сюда ещё бы посмотрел: https://learn.microsoft.com/en-us/windows/win32/procthread/multimedia-class-scheduler-service

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...