Главная » Ядро Linux » Информация  о времени  в ядре

0

Концепция времени для компьютера является несколько неопределенной. В действительности, для  того  чтобы  получать  информацию о времени и управлять  системным временем, ядро должно  взаимодействовать с системным аппаратным обеспечением. Аппаратное обеспечение предоставляет системный таймер, который используется ядром  для измерения времени. Системный таймер  работает  от электронного эталона времени, такого  как  цифровые электронные часы  или  тактовый генератор процессора. Интервал времени системного таймера  периодически истекает (еще говорят таймер срабатывает— hitting, popping) с определенной запрограммированнойчастотой.Этачастотаназываетсячастотойимпульсовтаймлра,(tickrate). Когда  срабатывает системный таймер, он генерирует прерывание, которое  ядро  обрабатывает с помощью специального обработчика прерывания.

Так как в ядре есть информация о запрограммированной частоте  следования импульсов  таймера, ядро  может  вычислить интервал времени между двумя успешными прерываниями таймера. Этот интервал называется временной отметкой  или импульсом таймера (tick)  и в секундах равен единице, деленной на частоту импульсов. Как будет показано дальше, именно таким  способом ядро  отслеживает абсолютное время  (wall time)  и время  работы  системы (uptime). Абсолютное время— это фактическое время дня, которое  наиболее важно  для пользовательских приложений. Ядро  отслеживает это время  просто  потому, что оно  контролирует прерывание таймера. В ядре  есть семейство системных вызовов, которое  позволяет пользовательским приложениям получать  информацию о дате и времени дня.  Это необходимо, так как  многие  программы  должны  иметь  информацию о ходе времени. Разница между двумя значениями времени работы системы — "сейчас" и "позже" — это простой способ  измерения относительности событий.

Прерывание таймера  очень  важно  для управления работой всей  операционной системы. Большое количество функций ядра  действуют  и завершаются в соответствии  с ходом  времени. Следующие действия периодически выполняются системным таймером.

• Обновление значения времени работы  системы (uptime).

• Обновление значения абсолютного времени (time  of day).

• Для SMP-систем выполняется проверка балансировки очередей выполнения планировщика, и если они  не сбалансированы, то их необходимо сбалансировать (как  было рассказано в главе 4, "Планирование выполнения процессов").

• Проверка, не израсходовал ли текущий процесс свой квант  времени, и  если израсходовал, то выполнятся планирование выполнения нового  процесса (как  это было рассказано в главе 4).

• Выполнение обработчиков всех динамических таймеров, для  которых истек  период  времени.

• Обновление статистики по использованию процессорного времени и других ресурсов.

Некоторые из этих действий выполняются при каждом  прерывании таймера, т.е. эта работа  выполняется с частотой  системного таймера. Другие  действия также  выполняются периодически, но только  через каждые  п прерываний системного таймера. Иными словами, эти функции выполняются с частотой, которая равна  некоторой доле частоты  системного таймера. В разделе  "Обработчик прерываний таймера" будет рассмотрена сама функция обработки прерываний системного таймера.

Частота импульсов таймера: HZ

Частота  системного таймера  (частота  импульсов, tick rate)  программируется при загрузке  системы на основании параметра ядра НZ, который определен с помощью директивы препроцессора. Значение параметра HZ  отличается для различных поддерживаемых  аппаратных платформ. На  самом  деле, для  некоторых аппаратных платформ значение параметра HZ  отличается даже для разных типов  машин.

Данный параметр ядра определен в файле  <asm/param.h>. Частота  системного таймера  равна  значению параметра HZ, период  таймера  равен  1/HZ. Например, в файле  include/asm-i386/param.h для  аппаратной платформы i386 этот  параметр определен следующим образом.

#define HZ 1000 /* internal kernel time frequency */

Поэтому для  аппаратной платформы i368 прерывание таймера  генерируется с частотой  1000 Гц, т.е.  1000 раз в секунду  (каждую  тысячную долю  секунды  или  одну миллисекунду). Для  большинства других  аппаратных платформ значение частоты системного таймера  равно  100 Гц.  В табл. 10.1 приведен полный список всех поддерживаемых аппаратных платформ и определенных для них  значений частоты  системного таймера.

При  написании кода ядра нельзя  считать, что параметр HZ  имеет  определенное заданное значение. В наши  дни это уже не такая  часто  встречающаяся ошибка, так как  поддерживается много  различных аппаратных платформ с разными частотами системного таймера. Раньше аппаратная платформа Alpha была  единственной, для которой частота  системного таймера  отличалась от 100 Гц, и часто  можно  было встретить  код, в котором жестко  было  прописано значение 100 там, где нужно  использовать параметр HZ.  Примеры использования параметра HZ  в коде ядра будут приведены ниже.

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

Таблица 10.1 . Значение частоты системного таймера

Аппаратная платформа                            Частота (в герцах)

alpha arm cris h8300 i386 ia64 m68k

m68knommu mips

mips64

parisc ppc ppc64 s390 sti spare

sparc64 um

v850

x86-64

32 или 10242

50, 100 или 1000

100 или 1000

24,100или122

Идеальное значение параметра HZ

Для аппаратной платформы i386, начиная с самых первых  версий  операционной системы Linux, значение частоты  системного таймера  было  равно  100 Гц.  Однако во время  разработки ядер  серии  2.5 это  значение было  увеличено до  1000 Гц, что (как  всегда бывает  в подобных ситуациях) вызвало  споры.  Так как  в системе  очень многое  зависит  от прерывания таймера, то изменение значения частоты  системного таймера  должно  оказывать сильное влияние на систему.  Конечно, как  в случае больших, так и в случае маленьких значений параметра HZ  есть свои  положительные и отрицательные стороны.

Увеличение значения частоты  системного таймера  означает, что обработчик прерываний таймера  выполняется более  часто.  Следовательно, вся работа, которую  он делает, также  выполняется более  часто.  Это позволяет получить  следующие преимущества.

• Прерывание таймера  имеет  большую  разрешающую способность по времени, и следовательно, все событии, которые выполняются во времени, также имеют большую  разрешающую способность.

• Увеличивается точность  выполнения событий во времени.

2  Эмулятор платформ ы IA-64 имее т частоту 32 Гц. Настояща я машина платформ ы IA-64 имее т частоту 1024 Гц.

•••

Разрешающая способность увеличивается во столько  же раз, во сколько раз возрастает  частота  импульсов. Например,  гранулярность таймеров при  частоте  импульсов 100 Гц равна  10 миллисекунд. Другими  словами, все периодические события выполняются прерыванием таймера, которое  генерируется с предельной точностью по времени, равной 10 миллисекунд, и большая точность3  не гарантируется. При  частоте, равной 1000 Гц, разрешающая способность равна  1 миллисекунде, т.е. в 10 раз выше.  Хотя ядро  позволяет создавать  таймеры с временным разрешением, равным

1 миллисекунде, однако  при  частоте  системного таймера  в 100 Гц нет возможности гарантированно получить  временной интервал, короче  10 миллисекунд.

Точность измерения времени также  возрастает аналогичным образом. Допустим, что таймеры ядра запускаются в случайные моменты времени, тогда в среднем  таймеры  будут срабатывать с точностью по времени до половины периода прерывания таймера, потому  что период  времени таймера  может  закончиться в любой  момент, а обработчик таймера  может выполниться, только  когда генерируется прерывание таймера.  Например, при  частоте  100 Гц описанные события в среднем  будут возникать с точностью +/ 5 миллисекунд от желаемого момента времени. Поэтому ошибка измерения в среднем  составит  5 миллисекунд. При  частоте  1000 Гц ошибка измерения в среднем  уменьшается до 0.5 миллисекунд — получает  десятикратное улучшение.

Более  высокое разрешение и большая точность  обеспечивают следующие преимущества.

• Таймеры ядра  выполняются с большим разрешением и с лучшей  точностью (это позволяет получить  много  разных улучшений, некоторые из которых  описаны дальше).

• Системные вызовы, такие как pol l ()  и selec t (), которые позволяют при желании  использовать время  ожидания (timeout) в качестве  параметра, выполняются с большей точностью.

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

• Вытеснение процессов выполняется более правильно.

Некоторые из  наиболее заметных улучшений производительности — это  улучшения точности измерения периодов времени ожидания при  выполнении системных  вызовов pol l ()  и selec t () . Это улучшение может  быть достаточно большим. Прикладная  программа, которая интенсивно использует эти  системные вызовы, может  тратить  достаточно много  времени, ожидая  на прерывания таймера, хотя в действительности интервал времени ожидания уже истек.  Следует  вспомнить, что средняя ошибка измерения времени (т.е. потенциально зря потраченное время)  равна половине периода прерывания таймера.

Еще  одно  преимущество более  высокой частоты  следования импульсов таймера— это  более  правильное вытеснение процессов, что проявляется в уменьшении задержки за счет планирования выполнения процессов. Вспомним из материала главы 4, что прерывание таймера  ответственно за уменьшение кванта  времени вы-

3   Здесь  имеется  в виду не точност ь измерения ,  а точност ь в вычислительно м плане.  Точность  измерени я  (в  общенаучном  смысле)  — это  статистическая мера повторяемост и  результата.  В вычислительном  (компьютерном) смысле  точность — это количество  значащих  цифр ,  которы е используются  для  представления  того или  другого  значения.

полняющегося  процесса.  Когда это значение уменьшается до нуля, устанавливается флаг need_resched , и ядро активизирует планировщик как только появляется  такая возможность. Теперь рассмотрим ситуацию, когда процесс в данный момент выполняется  и у него остался квант времени,  равный 2 миллисекундам.  Это означает, что через 2 миллисекунды планировщик должен вытеснить этот процесс и запустить на выполнение  другой процесс.  К сожалению,  это событие не может произойти  до того момента,  пока не будет сгенерировано  следующее прерывание  таймера.  В самом худшем случае следующее прерывание  таймера может возникнуть  через  1/HZ секунд! В случае, когда параметр HZ=100,  процесс может получить порядка 10 лишних миллисекунд. Конечно,  в конце концов все будет сбалансировано  и равнодоступность ресурсов не нарушится,  потому что все задания планируются  с одинаковыми ошибками,  и проблема состоит не в этом. Проблемы возникают из-за латентности, которую вносят задержки вытеснения  процессов.  Если задание,  которое планируется на выполнение, должно выполнить какие-нибудь  чувствительные ко времени действия,  как,  например,  заполнить  буфер аудиоустройства, то задержка не допустима. Увеличение частоты до 1000 Гц уменьшает задержку планировщика в худшем случае до 1 миллисекунды,  а в среднем — до 0.5 миллисекунды.

Должна,  однако,  существовать и обратная  сторона увеличения  частоты системного таймера,  иначе она была бы с самого начала равна 1000 Гц (или даже больше). На самом деле существует одна большая  проблема.  Более высокая  частота вызывает более частые прерывания  таймера,  что означает большие накладные  затраты.  Чем выше частота, тем больше времени  процессор должен тратить на выполнение  прерываний  таймера.  Это приводит не только к тому, что другим задачам отводится меньше процессорного  времени,  но и к периодическому  трешингу (trashing) кэша процессора (т.е. кэш заполняется данными,  которые не используются процессором). Проблема,  связанная  с накладными  расходами,  вызывает споры. Ясно,  что переход от значения  HZ=100  до значения  HZ=1000  в 10 раз увеличивает накладные затраты, связанные  с прерываниями таймера. Однако от какого реального значения  накладных затрат следует отталкиваться?  Если "ничего" умножить на 10, то получится тоже "ничего". Решающее соглашение  состоит в том, что по крайней  мере для современных систем,  значение  параметра HZ=1000  не приводит к недопустимым  накладным затратам. Тем не менее для ядер серии 2.6 существует возможность  скомпилировать ядро с другим значением  параметра HZ4.

Возможна ли операционная система без периодических отметок времени

Может  возникнуть  вопрос,  всегда  ли для функционирования операционной системы  необходимо  использовать  фиксированное  прерывание  таймера?  Можно  ли создать  операционную  систему, в которой не используются периодические отметки времени? Да, можно, но результат будет не очень привлекательным.

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

4     В связи  с ограничениям и аппаратно й платформ ы и протокол а NTP,   значени е переменно й HZ  не может быт ь произвольным. Дл я  платформ ы х86 значени я  100,  500 и  1000 работают  хорошо .

Когда обработчик таймера сработает, создается новый таймер для следующего события и так повторяется постоянно. При таком подходе не требуется периодическое прерывание таймера и нет необходимости в параметре HZ .

Однако при указанном подходе необходимо решить две проблемы. Первая проблема — это как в таком случае реализовать концепцию периодических отметок времени, хотя бы для того, чтобы ядро могло отслеживать относительные интервалы времени.  Эту проблему решить не сложно. Вторая проблема — это как избежать накладных затрат, связанных с управлением динамическими таймерами, даже при наличии оптимизации. Данную проблему решить сложнее. Накладные расходы и сложность реализации получаются настолько высокими, что в операционной системе Linux такой подход решили не использовать. Тем не менее так пробовали делать, и результаты получаются интересными. Если интересно, то можно поискать в Интернет-архивах.

Источник: Лав,  Роберт. Разработка ядра  Linux, 2-е  издание. : Пер.  с англ.  — М.  : ООО  «И.Д.  Вильяме» 2006. — 448 с. : ил. — Парал. тит. англ.

По теме:

  • Комментарии