Вопрос или проблема
У меня есть вопрос по поводу поддержки “реального времени” в Linux/Ubuntu:
После некоторых исследований на эту тему становится ясно, что поддержка “реального времени” в Linux имеет два аспекта: с одной стороны, это патч PREEMPT_RT, который добавляет возможности “вычислений в реальном времени” в ядро Linux; с другой стороны, это так называемые “стратегии планирования” в реальном времени, такие как SCHED_FIFO
, SCHED_RR
и SCHED_DEADLINE
, которые доступны уже долгое время.
Но как это все сочетается?
Что происходит, если я использую одну из “стратегий планирования в реальном времени” (например, SCHED_DEADLINE
) на “ванильном” ядре, то есть на том, в котором не активирован PREEMPT_RT
? Можно было бы предположить, что это даже невозможно. Но кажется, что это возможно, судя по моему тесту на “ванильном” (нереальном времени) ядре! Что это значит? Работают ли стратегии “в реальном времени” с “нереальным временем” ядра, просто не так “хорошо”? Или это означает, что “стратегии планирования в реальном времени” молча эквивалентны SHED_OTHER
при работе на “нереальном времени” ядре?
Кроме того, предположим, что я использую “ядро реального времени”, то есть то, в котором активирован PREEMPT_RT
: Будет ли какая-либо разница по сравнению с “ванильным” (нереальным временем) ядром, если я не запускаю явно какие-либо процессы с одной из “стратегий планирования в реальном времени”?
(Бонусный вопрос: Как “доброта” сочетается с планированием “в реальном времени”? Я искал информацию, но все источники объясняют “доброту” только в контексте SHED_OTHER
.)
Стратегии планирования и “предприятие” ядра — это отдельные, но взаимодополняющие аспекты.
Стратегии планирования определяют, как планировщик выбирает, какую задачу выполнить следующей, всякий раз, когда от него требуется пересчитать расписание. Это можно реализовать в значительной степени независимо от того, насколько часто (и может ли) ядро быть прервано, и они действительно оказывают влияние даже на нерелайновых ядрах — разумное применение стратегий и приоритетов обеспечивает выполнение важных задач раньше.
Однако, достижение “планирования в реальном времени”, то есть планирования с дедлайнами, требует обеспечения возможности выполнения задач к определенному времени. Здесь и вступает в игру “предприятие” ядра. Исторически ядро не могло быть прервано, поэтому, когда ядро было занято, задачи не могли быть запланированы (на данном ядре ЦП). Но, как описано в man 7 sched
:
Начиная с Linux 2.6.18, Linux постепенно оборудуется
возможностями реального времени, большинство из которых происходят из бывшего
realtime-preempt патч-сета.
Ядро постепенно добавляет все больше и больше возможностей стиля реального времени, кульминацией чего является PREEMPT_RT
, который стал доступен в основном ядре на нескольких архитектурах в версии 6.12:
Эта опция превращает ядро в ядро реального времени, заменяя
различные примитивы блокировки (спинлоки, rwlock и т.д.) на их
версии с учетом предвосхищаемого приоритета, внедряя
потоковую обработку прерываний и вводя механизмы для разделения длинных
непрерывно неизменяемых секций. Это делает ядро, за исключением очень
низкоуровневых и критических кодовых путей (входной код, планировщик, низкоуровневое
обработка прерываний), полностью прерываемым и помещает большую
часть контекстов выполнения под контроль планировщика.
Последнее предложение объясняет, как все это сочетается: повышение “предприятия” ядра связано с предоставлением большего контроля планировщику, что позволяет ему лучше удовлетворять требования, предъявляемые к нему различными стратегиями.
Таким образом, различные стратегии влияют даже на нелoyalno пути (поскольку они меняют то, как планировщик выбирает следующую задачу для выполнения), и PREEMPT_RT
имеет значение даже если используется только SCHED_OTHER
(поскольку это приводит к большему количеству возможностей для планировщика для переключения задач).
Смотрите также Почему кто-то предпочел бы не использовать ядро с низкой задержкой? и документацию ядра о различных типах блокировок, которые оно поддерживает.
“Доброта” не принимается в расчет при планировании с использованием SCHED_FIFO
, SCHED_RR
или SCHED_DEADLINE
.
.
Ответ или решение
Вопрос о том, как "ванильное" ядро Linux обрабатывает планирование в реальном времени, связан с двумя важными аспектами: наличием поддержки реального времени, предоставляемой через патч PREEMPT_RT, и стратегиями планирования, такими как SCHED_FIFO, SCHED_RR и SCHED_DEADLINE. Оба элемента играют важную роль, но обладают разными функциями и применяются в различных контекстах.
Теория
Понимание стратегий планирования и предвариативности ядра является ключом к пониманию поддержки реального времени в Linux.
Стратегии планирования в реальном времени — это методы, используемые ядром для выбора задач, которые должны выполняться в первую очередь. Эти стратегии включают SCHED_FIFO (планирование с фиксированным приоритетом), SCHED_RR (планирование с фиксированным приоритетом с круговым переключением) и SCHED_DEADLINE (планирование по сроку выполнения). Эти методы управления задачами были интегрированы в ядро уже на протяжении длительного времени и не зависят напрямую от наличия патча PREEMPT_RT. Их основная цель — обеспечить выполнение критических задач с минимальной задержкой.
PREEMPT_RT — это патч, который модернизирует ядро, добавляя возможности реального времени. Этот патч оптимизирует ядро, заменяя базовые механизмы блокировок, такие как спинлоки и rwlocks, на перерывные версии с учётом приоритета, а также вводя механизмы для разбиения длительных участков неприерывного кода. Это позволяет ядру стать практически полностью прерываемым, за исключением некоторых низкоуровневых важных путей выполнения, что увеличивает количество моментов, когда планировщик может переключать задачи.
Пример
Предположим, у вас есть критическая задача, которая должна выполняться в ограниченные временные рамки. На "ванильном" ядре вы можете установить планирование задач с помощью SCHED_DEADLINE, чтобы попытаться обеспечить выполнение задачи в требуемый момент. Однако, в отсутствие PREEMPT_RT, гарантия того, что задача не будет прервана ядром на длительное время, меньше. Это связано с тем, что, хотя стратегии планирования и определяют приоритеты задач, без поддержки PREEMPT_RT ядро может в некоторых случаях не иметь возможности быстро переключиться на нужную задачу.
При использовании ядра с PREEMPT_RT задача получает преимущество в виде большей гибкости и отзывчивости от ядра благодаря сокращению времени, в течение которого ядро не может быть прервана. Это изменение позволяет планировщику удовлетворять временные ограничения задач с большей точностью и надежностью.
Применение
Если вы используете "реальное" ядро (с поддержкой PREEMPT_RT), ваши задачи с планировании реального времени будут иметь преимущества в виде более быстрой реакции системы. Однако если вы не используете никакие специальные стратегии планирования в реальном времени, различия могут быть менее очевидными для стандартных задач, управляемых через SCHED_OTHER, обычный планировщик Linux. PREEMPT_RT в этом случае будет просто обеспечивать общую более высокую отзывчивость системы.
Эффект от использования PREEMPT_RT может быть критически важен для приложений, требующих строгих временных рамок, таких как системы автоматического управления или мультимедийные приложения в реальном времени. В таких ситуациях внедрение ядра PREEMPT_RT, вкупе с правильными стратегиями планирования, может существенно улучшить общую надежность и производительность системы.
Что касается комбинации с "обеспечением приоритетов" (niceness), то niceness не учитывается при использовании SCHED_FIFO, SCHED_RR или SCHED_DEADLINE. Эти стратегии сосредоточены на моментах выполнения задач, что снижает значимость понятия "прилива" в контексте линейного приоритета SCHED_OTHER.
Адаптация системы под нужды реального времени требует не только выбора правильных стратегий планирования, но и понимания работы всего экосистемы Linux, в частности, каких профилей нагрузки и поведения можно ожидать от системы при разных настройках и с разными задачами.