7.2.3 Задержка планировщика

Предыдущая  Содержание  Следующая V*D*V

Среди всех обсуждённых задержек, задержка планировщика является основной причиной увеличенного времени отклика ядра. Некоторые причины для больших задержек планировщика в ранних ядрах Linux версии 2.4 заключаются в следующем:

 

Ядро по своей натуре не вытесняющее: решения о планировании принимаются ядром в таких местах, как возвращение из прерывания или возвращение из системного вызова, и так далее. Однако, если текущий процесс выполняется в режиме ядра (то есть выполняется системный вызов), решение откладывается, пока процесс не возвращается в пользовательский режим. Это означает, что высокоприоритетный процесс не может вытеснить процесс с низким приоритетом, если последний выполняет системный вызов. Таким образом, из-за невытесняющей природы режима выполнения ядра, задержки планирования могут варьироваться от десятков до сотен миллисекунд, в зависимости от продолжительности системного вызова.

Моменты запрета прерываний: решение о планирования принимается уже при возвращении из следующего прерывания по таймеру. Если в течение длительного времени отключены все прерывания, прерывание от таймера задерживается, тем самым увеличивая задержку планирования.

 

Чтобы уменьшить задержку планирования в Linux, было приложено немало усилий. Усилия прилагаются в двух направлениях: вытеснение в ядре и патчи для снижения задержки.

 

Вытеснение в ядре

 

Так как поддержка симметричной многопроцессорной обработки в Linux возросла, его инфраструктура блокировки также начала улучшаться. Было идентифицировано много критических секций и они были защищены с помощью спин-блокировок. Было отмечено, что  вытеснение процесса, выполняющегося в режиме ядра, безопасно, если он не находится в какой-либо критической секции, защищённой с помощью спин-блокировки. Это свойство было использовано поставщиком встраиваемого Linux MontaVista, и они представили патч для поддержки вытеснения в ядре. Патч был включён в основную линейку ядра во время разработки версии 2.5 и в настоящее время поддерживается Робертом Лавом.

Поддержка вытеснения в ядре ввела в структуру задачи процесса новый член preempt_count. Если preemp_count равен нулю, ядро может быть вытеснено безопасно. Вытеснение ядра запрещено при ненулевом preempt_count. Работа с preemp_count происходит с помощью следующих основными макросов:

 

preempt_disable: запрет вытеснения путём увеличения на единицу preemp_count.

preempt_enable: уменьшение preemp_count на единицу. Вытеснение разрешено только если счётчик достиг нуля.

 

Чтобы соответствующим образом вызывать макросы preempt_disable и preempt_enable, были модифицированы все процедуры спин-блокировки. Процедуры спин-блокировки вызывают preempt_disable на входе, а процедуры разблокировки вызывают preempt_enable при выходе. Архитектурно-зависимые файлы, содержащие ассемблерный код для возврата из прерываний, и системные вызовы также были изменены так, чтобы проверять preempt_count до принятия решений о планировании. Если этот счётчик равен нулю, планировщик вызывается независимо от того, находится ли процесс в режиме ядра, или в пользовательском режиме.

Для более подробной информации смотрите, пожалуйста файлы include/linux/preempt.h, kernel/sched.c и arch/<your-arch>/entry.S в исходных текстах ядра. Как уменьшается задержка планировщика, когда в ядро вносится вытеснение, показывает Рисунок 7.1.

 

Рисунок 7.1 Задержка планировщика в ядрах с вытеснением и без вытеснения.

Рисунок 7.1 Задержка планировщика в ядрах с вытеснением и без вытеснения.

 

Патчи для уменьшения времени задержки

 

Патчи для уменьшения времени задержки от Инго Молнара и Эндрю Мортона направлены на снижение задержки планирования через добавление явных точек планирования в блоки кода ядра, которые выполняются за более длительный срок. Были идентифицированы такие участки кода (например, перебор длинного списка какой-либо структуры данных). Такие куски кода были переписаны, чтобы безопасно ввести точку планирования. Иногда это влекло освобождение спин-блокировки, выполнение перепланирования, а затем новый захват блокировки. Это называется прерыванием блокировок.

При использовании патчей для уменьшения времени задержки максимальная задержка планирования снижается до максимального времени между двумя точками перепланирования. Поскольку эти патчи настраивались довольно долгое время, они выполняются на удивление хорошо. Задержка планирования может быть измерена с помощью инструмента Schedstat. Вы можете загрузить патч с http://eaglet.rain.com/.

Измерения показывают, что наилучший результат даёт использование одновременно и вытеснения в ядре, и патчей для снижения времени задержки.

 

Предыдущая  Содержание  Следующая