jcxz 223 3 часа назад Опубликовано 3 часа назад · Жалоба Вопрос несколько не по теме форума, но наверняка актуальный для многих при работе с железом из 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()) рабочему потоку и снова ложится спать. Больше ничего не делает. Но оба этих метода работают не очень хорошо. Потестил программу в течение некоторого времени параллельно с обычной работой на двух разных ПК (ничего особенного - обычный набор программ: браузеры, компиляторы и т.п.) с разными win (Win7, Win11). Сделал сбор статистики периодичности вызовов функций пинания рабочего потока. Получаю такую картину: С префикса "mmTimer" - статистика по вызовам мультимедиа-таймера. "Thread" - по вызовам из спец.потока. Статистика накоплена за время работы - немногим более часа. 3 столбца = минимальное/среднее/максимальное время между вызовами. Как видно - разброс получился довольно значительный. Хоть ПК, на котором это работало - современный AMD Ryzen (6 ядер / 12 потоков) и не загружен особо. Почему так? Причём (как видно) - "Thread"-метод довольно хорошо держит нижнюю границу (отклонение менее 1 ms). Но зато - плохо держит верхнюю границу. Иногда возникают какие-то задержки аж на почти 70ms сверх положенного! Да и в среднем - отклонение больше, чем у ММ-таймера. А мультимедиа-таймер лучше держит средний интервал, но очень плохо - нижний интервал (а это самый критичный для меня параметр). Причём - это в данном запуске теста нижний интервал упал всего до ~8.2 ms. В другом запуске на другом ПК он падал ещё ниже. Так вот: Может кто подсказать ещё другие способы получения событий потоку (пинания потока) в Win с более высокой точностью/стабильностью? Пинания с обычного уровня пользовательского приложения. Кроме двух вышеприведённых испытываемых. PS: Все данные измерений времени получены от службы аппаратного таймера - QueryPerformanceFrequency()/QueryPerformanceCounter(). Поэтому думаю - достоверны. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 61 2 часа назад Опубликовано 2 часа назад · Жалоба Как-то очень давно в 7 или даже XP, опрашивал параллельным ещё портом какой-то микрометр с ~2кГц последовательным интерфейсом, через тупой опрос inp(), драйверами параллельного порта от avreal. Путём спихивания процесса руками через SetProcessAffinityMask на какое-нибудь ядро с номером повыше, чтобы там ему никто не мешал, работало вполне стабильно, но какой там именно был джиттер не проверял. Без этого, просто изменением приоритета, было хуже. Можно наверное ещё где-то шедулеру посоветовать определённые ядра не использовать другими процессами, чтобы там только он один крутился. я бы вот сюда ещё бы посмотрел: https://learn.microsoft.com/en-us/windows/win32/procthread/multimedia-class-scheduler-service Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться