Pull to refresh

Comments 13

Мне по этому поводу (или не по этому, а просто так) частенько вспоминается одна история: работал я как-то совместно с человеком, весьма неглупым, инженером-разработчиком, университетским преподавателем в области IT. И однажды обратил внимание, как запуская какую-то счетную задачу (матлаб что ли), он ставил ей наивысший приоритет «чтобы быстрее считало», после чего пару часов глядел в экран где даже курсор мыши двигался весьма неторопливо…
Угу. А ещё есть люди, которые на кондиционере ставят -16, чтобы посильнее холодило. :) Того же поля ягоды. :)
Я бы все же разделил софт и хард риалтайм.
То, что у вас описано — это софт риалтайм (тупо жадно забираем все ресурсы системы). По сути, если в системе есть софт-риалтайм нить или нити, все остальные нити становятся idle. Т.е. на самом деле это вообще не риалтайм, потому что никакое реальное время не гарантируется от слова совсем. Может быть повезет, а может и нет.

В харде же все просто: кто не успел, тот опоздал и будет немедленно убит. У каждой хард-рт задачи (job) есть таймер, до которого она должна закончиться. Если не успела — процесс убивается, ресурсы освобождаются, гипс снимают, клиент уезжает.
Это также означает, что другие задачи, у которых еще есть шансы успеть вовремя, получат больше ресурсов.
Ну, приведу наглядный пример: декодирование видео на пределе аппаратных возможностей. Нет смысла рендерить кадр, если его время уже прошло и сейчас нужно показывать уже следующий. В софт-риалтайме (все обычные системы), например, во время внезапного свопа или там глобальной сборки мусора видео тупо начнет тормозить (проигрываться с замедлением), а затем резко ускорится, чтобы нагнать тайминг. В хард-рт выпадут несколько кадров (просядет фпс), но рассинхрона не будет.
Для ядерного реактора, да и просто для любого банального промышленного робота, софт-рт подход неприменим. Ну представьте, несет промышленный робокран какую-нибудь тяжелую хрень на подвесе. Мозги ему выдают команды типа «перейти в позицию 11… перейти в позицию 12… перейти в позицию 13». Если время, во сколько точно выдаются команды, начнет сначала тормозить, а потом резво догонять, получится праща, которая может разрушить все вокруг. Если просто выпадет промежуточная команда «перейти в позицию 11.8», но команды «перейти в 11.7» и «перейти в 11.9» придут вовремя — за счет инерции последствия будут намного легче.
Есть разные модели хард риалтайма, и описание этих моделей в мои задачи на данном этапе не входило. Про выделение жёстких таймслотов я упомянул, а вот уже реакция на отказ — вопрос отдельный. Если у нас есть резервирование, и нить переиспользовала процессор, и мы считаем это проблемой, можно переключиться на горячий резерв. Но, вообще, это очень сложная тема. В анналах истории есть описание ситуации, в которой софт от старой ракеты перенесли на новую, новая полетела быстрее ожидаемого, в расчёте координат делитель оказался равным нулю и процессор упал в фолт. Система переключилась на резервный и он… тоже упрал в фолт — программа и данные-то те же самые. :)
«Реальное время: нити такого класса всегда вытесняют с процессора нити других классов так быстро, как это возможно»

Дмитрий, я просто предупреждаю что со времени появления защищенного режима процессоров Intel такой класс нитей исчез, условно на этом уровне работает операционная система, daemon триды там глобальные. Но вы что-то свое пилите, отказались из соображений безопасности. Чтобы нить реального времени не сломала что-то (умышленно или случайно). Просто предупреждаю, чтобы вы знали и не наступили на те же грабли, что инженеры Intel. Если вы делаете real time нити это нужно делать осознанно. Извините, пожалуйста, что несколько резкое замечание, но не мог не схватиться за маузер.

OS разные бывают. Всякие специализированные RTOS принципиально не имеют деления на user и kernel-space.


С другой стороны, у Linux есть группа RT приоритетов и оно, вроде как, даже работает. Конечно, что это особых привилегий процессу требует.


Post Scriptum я не специалист, поэтому могу ошибаться во втором абзаце.

Да деление на юзер и кернел тоже не очень принципиально. Очевидно, что если в realtime нити случился вечный цикл — система умерла. Где бы это ни было. Оживить можно, но это требует дополнительных механизмов, которые логически неочевидны и это отдельный разговор.
Нужно больше ядер
:) ну — представьте, что приложение с ошибкой запускает треды по числу ядер. часто так и делают, чтобы получить максимальную производительность.
1. Такой класс никуда не исчез.

2. «Даемон триды» — это тоже нити, у них тоже есть приоритет. Иногда именно такой. А ещё есть нити драйверов. И т.п.

3. Я описываю механизм, а не его применение. Конкретная ОС может запретить нитям пользователя иметь приоритеты выше некоторого предела, чтобы гарантировать себя от зависания по вине ошибочной программы пользователя. Или выставить пределы на фактическую загрузку процессора.

4. Все озвученные вопросы не имеют вообще никакого отношения к защищённому режиму процессоров Интел и вообще к процессору Интел. Они совершенно не зависят от процессора и всё вышесказанное специалистам по разработке ОС к моменту рождения компании Интел было более-менее известно.

Шикарный пост! Сам превратил черный ящик устройства многозадачности и работы планировщика (надо сказать, тоже достаточно примитивного) копаясь в недрах ThreadX, но такие посты прекрасно расставляют оставшиеся точки на i, а так же открывают глаза на некоторые тюки (например трюк с инверсией приоритетов), поэтому большое спасибо.

Кстати, в SMP системе шедулер ничем не отличается от однопроцессорного.

Я не знаю деталей, но мне кажется там есть немало нюансов связанных с накладными расходами на перенос треда с одного ядра на другое, и на правильное балансирование тредов между процессорами. Еще есть вопрос какое ядро/ядра должны заниматься планированием. Например у нас 2 ядра и есть один очень требовательный к cpu тред, а все остальные idle. В таком случае, возможно, лучше запускать планировщик на втором ядре, а первому просто подсовывать результат и по прерыванию он без всяких проверок будет выполнять тот тред который ему сказали.

Недавно наткнулся на интересную статью о багах в планировщике Linux, авторы которой обещают в среднем до 20% улучшения производительности при определенных задачах.
Вы правы — алгоритм назначения нити на процессор в SMP системах учитывает, на каком процессоре нить работала в предыдущем слоте, и предпочитает его.

Но это исключительно оптимизация. Если её не сделать, шедулер всё равно будет работать. Фактически, несколько процессоров занимаются назначением нити для себя совершенно самостоятельно и асинхронно.

Сама по себе привязка нити делается довольно просто — при выборе нити осуществляется некоторая сортировка нитей по признаку. Например, по приоритету. В релевантность этой сортировки можно подмешать бонус, если нить до этого исполнялась именно на данном процессоре, таким образом повысив её шансы этот же процессор и занять.
Sign up to leave a comment.

Articles