Что делает простаивающий процесс ЦП?

Что делает простаивающий процесс ЦП?

Глядя на источникstraceЯ нашел использование флага клонирования CLONE_IDLETASK, которое описано там как:

#define CLONE_IDLETASK 0x00001000 /* kernel-only flag */

Изучив вопрос более подробно, я обнаружил, что, хотя этот флаг не рассматривается, man cloneон фактически используется ядром во время процесса загрузки для создания простаивающих процессов (все из которых должны иметь PID 0) для каждого ЦП на машине. То есть на машине с 8 ЦП будет «запущено» не менее 7 (см. вопрос ниже) таких процессов (обратите внимание на кавычки).

Теперь это приводит меня к паре вопросов о том, что на самом деле делает этот "холостой" процесс. Я предполагаю, что он непрерывно выполняет операцию NOP, пока не закончится его временной интервал, и ядро ​​не назначит реальный процесс для запуска или снова назначит холостой процесс (если ЦП не используется). Но это всего лишь предположение. Итак:

  1. На машине, скажем, с 8 ЦП будет ли создано 7 таких бездействующих процессов? (и один ЦП будет удерживаться самим ядром, пока не будет выполняться работа в пользовательском пространстве?)

  2. Действительно ли процесс ожидания — это просто бесконечный поток операций NOP? (или цикл, который делает то же самое).

  3. Рассчитывается ли загрузка ЦП (например uptime) просто по тому, как долго процесс бездействовал на ЦП и как долго он отсутствовал в течение определенного периода времени?


PS Вероятно, что большая часть этого вопроса связана с тем, что я не до конца понимаю, как работает ЦП. То есть я понимаю сборку, временные рамки и прерывания, но я не знаю, как, например, ЦП может потреблять больше или меньше энергии в зависимости от того, что он выполняет. Я был бы благодарен, если бы кто-нибудь мог просветить меня и по этому поводу.

решение1

Задача бездействия используется для учета процессов, а также для снижения потребления энергии. В Linux одна задача бездействия создается для каждого процессора и привязывается к этому процессору; когда нет другого процесса для выполнения на этом процессоре, задача бездействия планируется. Время, проведенное в задачах бездействия, отображается как время «бездействия» в таких инструментах, как top. (Время безотказной работы рассчитывается по-другому.)

В Unix, похоже, всегда был какой-то цикл простоя (но не обязательно реальная задача простоя, см.ответ Жиля), и даже в V1он использовал WAITинструкциюкоторый останавливал процессор до тех пор, пока не произойдет прерывание (это означало «ожидание прерывания»). Некоторые другие операционные системы использовали циклы занятости, DOS,ОС/2, и ранние версии Windows в частности. Довольно долгое время процессоры использовали этот тип инструкции «ожидания» для снижения потребления энергии и выделения тепла. Вы можете увидеть различные реализации задач бездействия, например, вarch/x86/kernel/process.cв ядре Linux: базовый просто вызываетHLT, который останавливает процессор до тех пор, пока не произойдет прерывание (и включает режим энергосбережения C1), другие реализации обрабатывают различные ошибки или неэффективности (напримериспользуя MWAITвместо HLTна некоторых процессорах).

Все это полностью отделено от состояний простоя в процессах, когда они ожидают события (ввода-вывода и т. д.).

решение2

В учебнике по планировщику процессов, если у планировщика нет процесса для планирования (т. е. если все процессы заблокированы, ожидая ввода), то планировщик ждет прерывания процессора. Прерывание может указывать на ввод от периферийного устройства (действие пользователя, сетевой пакет, завершенное чтение с диска и т. д.) или может быть прерыванием таймера, которое запускает таймер в процессе.

Планировщик Linux не имеет специального кода для случая «ничего не делать». Вместо этого он кодирует случай «ничего не делать» как специальный процесс, процесс ожидания. Процесс ожидания планируется только тогда, когда никакой другой процесс не может быть запланирован (он фактически имеет бесконечно низкий приоритет). Процесс ожидания фактически является частью ядра: это поток ядра, т. е. поток, который выполняет код в ядре, а не код в процессе. (Точнее, есть один такой поток для каждого ЦП.) Когда выполняется процесс ожидания, он выполняет операцию ожидания прерывания.

То, как работает wait-for-interrupt, зависит от возможностей процессора. С самой базовой конструкцией процессора это просто занятая петля —

nothing:
    goto nothing

Процессор продолжает выполнять инструкцию ветвления вечно, что ничего не дает. Большинство современных ОС не делают этого, если только они не работают на процессоре, где нет ничего лучшего, а у большинства процессоров есть что-то лучшее. Вместо того, чтобы тратить энергию, ничего не делая, кроме обогрева комнаты, в идеале процессор должен быть выключен. Поэтому ядро ​​запускает код, который инструктирует процессор выключить себя или, по крайней мере, отключить большую часть процессора. Должна быть по крайней мере одна небольшая часть, которая остается включенной, контроллер прерываний. Когда периферийное устройство запускает прерывание, контроллер прерываний отправляет сигнал пробуждения основному (части) процессору.

На практике современные процессоры, такие как Intel/AMD и ARM, имеют множество сложных настроек управления питанием. ОС может оценить, как долго процессор будет находиться в режиме ожидания, и в зависимости от этого будет выбирать различные режимы с низким энергопотреблением. Режимы предлагают различные компромиссы между потреблением энергии в режиме ожидания и временем, необходимым для входа и выхода из режима ожидания. На некоторых процессорах ОС также может понижать тактовую частоту процессора, когда обнаруживает, что процессы не потребляют много процессорного времени.

решение3

Нет, простаивающая задача не тратит циклы ЦП. Планировщик просто не выбирает простаивающий процесс для выполнения. Простаивающий процесс ждет некоторого события, чтобы продолжить работу. Например, он может ждать ввода в системном read()вызове.

Кстати, ядро ​​— это не отдельный процесс. Код ядра всегда выполняется в контексте процесса (ну, за исключением особого случая потока ядра), поэтому неправильно говорить «и один процессор будет удерживаться самим ядром, пока не будет выполняться работа в пользовательском пространстве».

Связанный контент