Хабрахабр

[Перевод] Чем заняться процессору, когда нечего делать?

Разумно было бы предполагать, что для ядра довольно легко будет ничего не делать – но это не так. На конференции Kernel Recipes 2018Рафаэль Высоцкий рассказал о том, чем занимаются процессоры, когда им нечего делать, как это обрабатывает ядро, какие у текущей стратегии есть проблемы, и как его недавняя работа над циклом бездействия улучшила ситуацию с энергопотреблением систем, которые ничего не делают.

Высоцкий очень точно дал все определения: CPU – это такая сущность, которая может принимать инструкции из памяти и выполнять их одновременно с другими сущностями в той же системе, занимающимися тем же самым. Цикл бездействия, одна из подсистем ядра, которую поддерживает Высоцкий, управляет тем, что делает CPU, когда ему не нужно исполнять никаких процессов. Если у процессора несколько ядер, то каждое из этих ядер – CPU. На простейшей однопроцессорной системе с одним ядром этим ядром является CPU. Или, точнее, у ядра Linux есть несколько внутренних классов для диспетчеризации, один из которых – особый класс бездействия (idle). Если у каждого из ядер есть несколько интерфейсов для одновременного исполнения инструкций – Intel называет такую систему "гиперпоточностью" – тогда каждый из этих потоков будет CPU.
CPU бездействует, когда у него нет задач для выполнения. Если оборудование этого не разрешает, тогда CPU придётся выполнять бесполезную инструкцию, пока не подвернётся настоящая работа. Если на данном CPU ни в одном из классов, исключая класс бездействия, нет задач, то CPU считается бездействующим. Однако это чрезвычайно неэффективное использование электричества, поэтому большинство процессоров поддерживают несколько состояний с низким потреблением энергии, в которые их переводит ядро до тех пор, пока они не потребуются для выполнения полезной работы.

На вход и выход требуется время, а кроме того, при входе в это состояние немного повышается энергопотребление текущего состояния, а при выходе из него – потребление того состояния, в которое переходит процессор. В состояние бездействия нельзя просто так войти или выйти из него. Это значит, что в случае кратких периодов бездействия лучшим использованием ресурсов компьютера будет неглубокое бездействие; для более долгих периодов стоимость перехода в более глубокое состояние бездействия будет оправдано увеличением количества сэкономленной энергии. И хотя чем глубже состояние бездействия, тем меньше энергии потребляет процессор, стоимость входа и выхода в такие состояния растёт. Это задача цикла бездействия. Поэтому в интересах ядра предсказать, как долго процессор будет бездействовать, перед тем, как решить, насколько глубокое состояние бездействия ему нужно.

Тогда планировщик вызывает регулятор, который старается выдать наилучшее предсказание подходящего состояния бездействия, в которое можно войти. В этом цикле планировщик замечает, что CPU бездействует, так как у него нет никаких задач, которые можно было бы ему поручить. Они используются в разных случаях, но оба пытаются делать примерно одно и то же: отслеживать состояние системы при переходе CPU в состояние бездействия и время, которое он провёл в бездействии. Сейчас в ядре есть два регулятора, menu и ladder. Это делается для того, чтобы предсказать, как долго вошедший в состояние бездействия CPU в нём останется, и, следовательно, какое именно состояние наилучшим образом подойдёт для данной ситуации.

Планировщик запускает этот таймер для разделения времени доступа к CPU: если на одном процессоре необходимо выполнять несколько задач, каждую из них можно выполнять только по чуть-чуть, а потом периодически откладывать в пользу другой задачи. Эту работу особенно усложняет таймер планировщика CPU. Более того, если позволить таймеру выполняться на бездействующем CPU, это не даст регулятору выбрать состояния глубокого бездействия, ограничивая промежутки, во время которых CPU находится в бездействии. Этот таймер не нужно выполнять на бездействующем CPU, поскольку задач, между которыми нужно делить CPU, не существует. 16 планировщик отключал таймер перед вызовом регулятора. Поэтому в ядрах вплоть до 4. Когда CPU пробуждался по прерыванию, планировщик решал, есть ли необходимые к выполнению задачи, и в случае их наличия заново запускал таймер.

Но если регулятор предсказывает долгий период простоя, а этот период оказывается коротким, то регулятор «проигрывает», поскольку стоимость входа в глубокое бездействие не окупается экономией энергии на коротком периоде бездействия. Если регулятор предсказывает долгий период простоя, и этот период действительно оказывается долгим, то регулятор «выигрывает»: CPU переходит в состояние глубокого бездействия, и энергия экономится. Или, иными словами, поскольку на остановку и запуск таймера тратятся ресурсы, нет смысла его останавливать, когда регулятор предсказывает короткий период простоя. Ещё хуже, когда регулятор предсказывает короткий период простоя – тогда он «проигрывает» вне зависимости от длительности простоя: если период оказался долгим, он упустил возможность сэкономить, а если коротким, то расходы на остановку и перезапуск таймера были потрачены впустую.

Он вернул цикл бездействия в ядре 4. Высоцкий решил попробовать поменять работу регулятора, но пришёл к выводу, что основная проблема состоит в том, что таймер останавливают перед вызовом регулятора, то есть, до того, как становится известным рекомендованное состояние бездействия. Если он предсказал долгий простой, таймер останавливается, чтобы не разбудить CPU раньше времени. 17, чтобы решение об остановке таймера принималось после того, как регулятор выдал свою рекомендацию. А это значит, что таймер выполняет и функцию безопасности, пробуждая CPU, если простой оказался более длинным, чем предсказывалось, и давая регулятору второй шанс на правильное решение. Если простой предполагается коротким, таймер оставляют, чтобы не тратить ресурсы на отключения.

Если работа есть, таймер по необходимости перезапускается. Когда бездействующий CPU пробуждается через прерывание, будь то не остановленный таймер или другое событие, планировщик сразу же принимает решение о наличии работы. Поскольку это означает, что регулятор теперь можно вызывать и когда таймер работает, и когда он не работает, регулятора необходимо вызвать, чтобы это учесть. Если её нет, вызывается регулятор.

В случае предсказания долгого бездействия таймер всё равно останавливается, поэтому тут ничего не меняется; мы выигрываем, если период простоя оказывается долгим, и проигрываем, если коротким. Изучив таблицу выигрышей и проигрышей, Высоцкий считает, что внесённые им изменения улучшат картину. Но если предсказан короткий период простоя, мы выигрываем: если период и правда окажется коротким, мы сэкономим на остановке и запуске таймера, а если длинным – не остановленный таймер разбудит нас и даст возможность сделать ещё одно предсказание.

Поскольку теория игр не может служить полноценной заменой реальной ситуации, Высоцкий проверил этот подход на множестве систем. График выше характерен для всех испытанных систем; он показывает зависимость энергопотребления от времени на бездействующей системе. Зелёная линия – старый цикл бездействия, красная – новый. По новой схеме энергии потребляется меньше, кроме того, она более предсказуема. Не на всех испытанных CPU получился такой большой разрыв между линиями, однако все они показали плоскую красную линию под неровной зелёной. Как сказал Высоцкий, эта новая схема реже предсказывает короткие периоды бездействия, но чаще оказывается правой по поводу их небольшой длительности.

В особенности от неё получат преимущество процессоры от Intel, поскольку у них имеется достаточно большой массив состояний бездействия, из которых регулятор может выбрать нужный, что даст ему наилучшие шансы на успех в случае правильного предсказания; но и процессоры ARM также получат преимущество от новой схемы. Отвечая на вопрос из аудитории, Высоцкий сказал, что эта работа зависит от архитектуры.

20% падение энергопотребления в состоянии бездействия может показаться незначительным достижением, но на самом деле это не так. Любая система, желающая достаточно хорошо справляться с пиковыми нагрузками, должна обладать запасом мощности в нормальном режиме, который проявит себя во время бездействия. На графике выше показано использование процессора за год на моём сервере, который занимается почтой, передачей файлов, VPN, NTP и т.п. Жёлтый цвет означает время простое. Экономия 20% этой энергии понравилась бы моему провайдеру, да и для планеты это было бы лучше.

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть