- Вопрос или проблема
- Фоновое знание
- Мотивация
- Увеличение sched_min_granularity_ns
- А возможно, и несколько других настроек
- Предложение, если ваша нагрузка имеет большое количество потоков/процессов
- Игнорируйте CONFIG_HZ
- Ответ или решение
- Как изменить длину временных интервалов, используемых планировщиком ЦПУ Linux?
- Обоснование
- Конфигурация CFS через настройки sysctl
- Применение изменений
- Общие рекомендации
- Советы по работе с несколькими потоками
- Заключение
Вопрос или проблема
Возможно ли увеличить длину временных срезов, которые планировщик процессора Linux позволяет процессу выполнять? Как я смогу это сделать?
Фоновое знание
Этот вопрос касается того, как уменьшить частоту, с которой ядро будет заставлять переключаться между различными процессами, выполняющимися на одном CPU. Это функция ядра, описываемая как “прерываемая многозадачность”. Эта функция, как правило, полезна, потому что она предотвращает то, чтобы отдельный процесс занимал CPU и делал систему полностью неотзывчивой. Однако переключение между процессами имеет свои издержки; таким образом, здесь существует компромисс.
Если у вас есть один процесс, который использует всё время CPU, которое может получить, и другой процесс, который взаимодействует с пользователем, то более частое переключение может уменьшить задержки в ответах.
Если у вас есть два процесса, которые используют всё время CPU, которое могут получить, то реже переключаться может позволить им сделать больше работы за то же время.
Мотивация
Я публикую это на основе моей первоначальной реакции на вопрос Как изменить частоту переключения контекста в Linux?
Я сам не хочу изменять временной срез. Однако я слабо помню, что это было актуально, с параметром сборки CONFIG_HZ
. Поэтому я хочу понять, какова текущая ситуация. Основан ли временной срез планировщика CPU всё ещё на CONFIG_HZ
?
Кроме того, на практике настройка времени сборки очень ограничительна. Для дистрибутивов Linux гораздо практичнее, если они могут иметь одно ядро на архитектуру CPU, и разрешать настройку его во время выполнения или, по крайней мере, во время загрузки. Если настройка временного среза всё ещё актуальна, есть ли новый метод, который не фиксирует его на этапе сборки?
Для большинства серверов RHEL7 RedHat предлагает увеличить sched_min_granularity_ns
до 10 мс и sched_wakeup_granularity_ns
до 15 мс. (Источник. Технически эта ссылка указывает 10 мкс, что в 1000 раз меньше. Это ошибка).
Мы можем попытаться понять это предложение более подробно.
Увеличение sched_min_granularity_ns
В текущих ядрах Linux временные срезы CPU выделяются задачам через CFS, полностью честный планировщик. CFS можно настроить, используя несколько параметров sysctl
.
kernel.sched_min_granularity_ns
kernel.sched_latency_ns
kernel.sched_wakeup_granularity_ns
Вы можете временно установить параметры sysctl до следующей перезагрузки или навсегда в конфигурационном файле, который применяется при каждой загрузке. Чтобы узнать, как применить этот тип настройки, посмотрите “sysctl” или прочитайте краткое введение здесь.
sched_min_granularity_ns
– самый заметный параметр. В оригинальном sched-design-CFS.txt это описывалось как единственный “настраиваемый” параметр, “для настройки планировщика от ‘настольного’ (низкие задержки) до ‘серверного’ (хорошая пакетная обработка) загрузок.”
Другими словами, мы можем изменить этот параметр, чтобы уменьшить накладные расходы от переключения контекста, и, следовательно, улучшить производительность в ущерб отзывчивости (“задержке”).
Я рассматриваю эту настройку CFS как имитирующую предыдущую настройку времени сборки, CONFIG_HZ. В первой версии кода CFS значение по умолчанию составляло 1 мс, что эквивалентно 1000 Гц для использования “настольного” типа. Другие поддерживаемые значения CONFIG_HZ составляли 250 Гц (по умолчанию) и 100 Гц для “серверного” конца. 100 Гц также было полезно при запуске Linux на очень медленных процессорах, это была одна из причин, указанных при добавлении CONFIG_HZ как параметры сборки на X86.
Звучит разумно попробовать изменить это значение до 10 мс (т.е. 100 Гц) и измерить результаты. Помните, что параметры sysctl измеряются в нс. 1 мс = 1,000,000 нс.
Мы видим, что эта старая настройка для ‘сервера’ была всё ещё очень актуальна в 2011 году, для производительности в некоторых тестах с высокой нагрузкой: https://events.static.linuxfound.org/slides/2011/linuxcon/lcna2011_rajan.pdf
А возможно, и несколько других настроек
Значения по умолчанию для трех вышеперечисленных параметров выглядят относительно близкими друг к другу. Это заставляет меня хотеть упростить вещи и умножить их все на одну и ту же величину :-). Но я попытался разобраться в этом, и кажется, что некоторые более специфические настройки могут быть также актуальны, поскольку вы настраиваете производительность.
sched_wakeup_granularity_ns
касается “прерывания на пробуждение”. Т.е. он контролирует, когда задача, пробужденная событием, может сразу прервать текущий выполняющийся процесс. Слайды 2011 года показали различия в производительности и для этой настройки.
Смотрите также “Отключить WAKEUP_PREEMPT” в этом справочнике IBM 2010 года, который предполагает, что “для некоторых загрузок” эта функция по умолчанию “может стоить несколько процентов использования CPU”.
SUSE Linux имеет документ, который предлагает установить этот параметр больше половины sched_latency_ns
, чтобы эффективно отключить прерывание на пробуждение, и что “короткие задачи с циклом работы не смогут эффективно конкурировать с захватчиками CPU”.
Документ SUSE также предлагает некоторые более детальные описания других параметров. Вы определенно должны проверить, каковы текущие значения по умолчанию на ваших собственных системах. Например, значения по умолчанию на моей системе, похоже, немного отличаются от того, что говорит документ SUSE.
https://www.suse.com/documentation/opensuse121/book_tuning/data/sec_tuning_taskscheduler_cfs.html
Если вы экспериментируете с любыми из этих переменных планирования, я думаю, вы также должны быть в курсе, что все три масштабируются (умножаются) на 1 + log_2 количества процессоров. Это масштабирование может быть отключено с помощью kernel.sched_tunable_scaling
. Я мог бы чего-то не замечать, но это кажется удивительным, например, если вы рассматриваете отзывчивость серверов, предоставляющих интерактивные приложения и работающих на полной/почти полной загрузке, и как эта отзывчивость будет меняться с количеством процессоров на сервер.
Предложение, если ваша нагрузка имеет большое количество потоков/процессов
Я также наткнулся на предложение 2013 года по поводу нескольких других настроек, которые могут обеспечить значительный прирост производительности, если ваша нагрузка имеет большое количество потоков. (Или, возможно, более точно, это восполняет производительность, которую они имели на ядрах до CFS).
- “Два необходимых изменения в ядре” – обсуждение на mailing list PostgreSQL.
- “Пожалуйста, увеличьте kernel.sched_migration_cost в профиле виртуального хоста” – ошибка Red Hat 969491.
Игнорируйте CONFIG_HZ
Я думаю, вам не нужно беспокоиться о том, на что установлен CONFIG_HZ
. Моё понимание заключается в том, что это не актуально в современных ядрах, при условии, что у вас разумное таймерное оборудование. Также смотрите коммит 8f4d37ec073c, “sched: high-res preemption tick”, найденный через этот комментарий в дискуссии о изменении: https://lwn.net/Articles/549754/.
(Если вы посмотрите на коммит, не стоит беспокоиться о том, что SCHED_HRTICK
зависит от X86
. Это требование похоже было снято в некоторых более поздних коммитах).
Похоже, вам нужен пакетный планировщик: используйте schedtool
, чтобы запускать процессы под разными планировщиками. Например, schedtool -B «Команда для выполнения в пакетном режиме»
.
Ответ или решение
Как изменить длину временных интервалов, используемых планировщиком ЦПУ Linux?
Изменение длины временных интервалов (тайм-слотов), которые планировщик ЦПУ Linux выделяет процессам, возможно, и может быть стратегически важным для оптимизации производительности системы в различных условиях загрузки. Это концепция тесно связана с понятием «предупреждающей многозадачности», благодаря которой операционная система может предотвращать доминирование одного процесса и обеспечивать отзывчивость системы.
Обоснование
Планировщик ЦПУ Linux, известный как CFS (Completely Fair Scheduler), определяет, как долго процесс может занимать ЦПУ, прежде чем управление будет передано другому процессу. Само по себе это позволяет системе быть отзывчивой при взаимодействии с пользователем, но в некоторых сценариях может потребоваться увеличение длительности тайм-слотов для повышения общей производительности.
Для изменения характеристик CFS в современных ядрах Linux можно использовать несколько параметров системы. Рассмотрим их подробнее.
Конфигурация CFS через настройки sysctl
Основные параметры, влияющие на поведение CFS, включают:
- kernel.sched_min_granularity_ns
- kernel.sched_latency_ns
- kernel.sched_wakeup_granularity_ns
Чтобы изменить данные параметры, вы можете использовать инструмент sysctl
, который позволяет временно изменять настройки или сохранять изменения в конфигурационных файлах для применения при запуске системы.
Увеличение sched_min_granularity_ns
Данный параметр определяет минимальное время, в течение которого процесс может абстрагироваться от переключений. Увеличение этого значения может уменьшить накладные расходы от контекстных переключений. Рекомендуется провести эксперименты с установкой этого параметра в 10 мс (10,000,000 нс).
Дополнительные настройки
kernel.sched_latency_ns
: Определяет общую длительность, в течение которой процессы могут быть запланированы.kernel.sched_wakeup_granularity_ns
: Контролирует, когда процессы, пробуждаемые событиями, могут предвосхитить текущую выполняемую задачу. Для оптимизации производительности, стоит установить это значение за пределами половиныsched_latency_ns
.
Применение изменений
Для временных изменений вы можете использовать команду:
sysctl -w kernel.sched_min_granularity_ns=10000000
sysctl -w kernel.sched_latency_ns=15000000
sysctl -w kernel.sched_wakeup_granularity_ns=12000000
Для постоянных изменений, добавьте соответствующие строки в файл /etc/sysctl.conf
:
kernel.sched_min_granularity_ns=10000000
kernel.sched_latency_ns=15000000
kernel.sched_wakeup_granularity_ns=12000000
После внесения изменений выполните команду:
sysctl -p
Общие рекомендации
- Измерение производительности: Перед и после изменения параметров рекомендуется использовать средства мониторинга и профилирования для оценки влияния на производительность системы.
- Тестирование в реальных условиях: Проведите тесты на производительность различных типов нагрузки (например, серверные задачи против интерактивных приложений), чтобы оценить влияние изменений.
Советы по работе с несколькими потоками
Если ваша рабочая нагрузка включает множество потоков, возможно, вам также стоит рассмотреть изменения следующих параметров:
kernel.sched_migration_cost
: Это значение может повлиять на количество контекстных переключений, особенно в условиях высокой нагрузки.
Заключение
Изменение длины временных интервалов в Linux через модификацию параметров CFS позволяет оптимизировать управление ресурсами системы в зависимости от конкретных требований ваших приложений. Это требует тщательной настройки и мониторинга, чтобы сбалансировать производительность и отзывчивость системы. Принимая во внимание современные вычислительные среды, такие изменения могут значительно повлиять на общую эффективность работы.