Я занимаюсь разработкой приложения, которое отвечает за перемещение и управление роботами через соединение UDP.
Приложение должно:
На данный момент я реализовал все вышеперечисленное. Тем не менее, приложение не может отправлять пакеты регулярно, когда сторожевой таймер активирован или когда два или более QTimer
объекты используются. Приложение, как правило, будет работать, но я не буду считать его «готовым к производству». Я пытался использовать точные флаги таймеров (Qt::Precise
, Qt::Coarse
а также Qt::VeryCoarse
), но у меня все еще были проблемы.
Заметки:
QTimer::singleShot()
(например, я отправлю следующий пакет только после отправки текущего пакета). Где мы используем таймеры:
Есть ли у вас какие-либо рекомендации по использованию объектов QTimer с критичным к производительности кодом (любая идея приветствуется). Обратите внимание, что я также пытался использовать разные потоки, но это вызвало у меня больше проблем, так как приложение не было бы синхронизировано, что не позволяло эффективно контролировать протестированных нами роботов.
На самом деле, я, кажется, недооценил производительность таймера Qt и цикла обработки событий. В моей системе я получаю в среднем около 20 тыс. Наносекунд на цикл обработки событий плюс накладные расходы от планирования вызова функции из очереди, а таймер с интервалом 1 миллисекунда редко опаздывает, большинство тайм-аутов на несколько тысяч наносекунд меньше миллисекунды. Но это система высокого класса, на встроенном оборудовании это может быть намного хуже.
Вы должны уделить время и профилировать вашу целевую систему и сборку Qt, чтобы определить, действительно ли она может работать достаточно быстро, и на основе этих измерений скорректировать время, чтобы компенсировать задержки системы, чтобы запланировать ваши события вовремя.
Вы должны определенно сохранять поток таймера настолько свободным, насколько это возможно, потому что, если вы заблокируете его с помощью ввода-вывода или обширных вычислений, ваш таймер не будет точным. Используйте выделенный поток для планирования работы и дополнительные рабочие потоки для выполнения фактической работы. Вы также можете попробовать поиграть с приоритетами потоков.
В худшем случае найдите сторонние высокопроизводительные реализации цикла событий или создайте свой собственный и, возможно, более быстрый механизм сигнализации, как ell. Как я уже упоминал в комментариях, сигналы очереди Qt между потоками очень медленные, по крайней мере по сравнению с чем-то вроде косвенных вызовов функций.
И последнее, но не менее важное: если вы хотите выполнять задачу X каждые N единиц времени, это будет возможно только в том случае, если задача X занимает в вашей системе N единиц времени или меньше. Вы должны учитывать это для каждой задачи и для всех задач, запущенных одновременно. И чтобы получить точное планирование, вы должны измерить, сколько времени заняло задание X, и, если его частота меньше, запланировать следующее выполнение за оставшееся время, иначе выполнить немедленно.
Других решений пока нет …