Добавлен: 29.10.2018
Просмотров: 48153
Скачиваний: 190
436
Глава 5. Ввод и вывод информации
вавшейся в предыдущих разделах: сначала будет рассмотрена их аппаратная, а затем
программная составляющие.
5.5.1. Аппаратная составляющая часов
В компьютерах обычно применяются два типа часов, которые совсем не похожи на те
часы, которыми люди пользуются в повседневной жизни. Простейшие часы подключа-
ются к электрической сети с напряжением 110 или 220 В и выдают прерывания каждый
цикл изменения напряжения с частотой 50 или 60 Гц. Ранее в основном применялись
именно такие часы, но сейчас они используются довольно редко.
Другая разновидность часов создается из трех компонентов (рис. 5.24): кварцевого
генератора, счетчика и регистра хранения. Если из кристалла кварца правильно вы-
резать пластину и подвести к ней напряжение, то ее можно заставить генерировать
очень стабильный периодический сигнал, как правило, в диапазоне от нескольких сотен
мегагерц до нескольких гигагерц в зависимости от выбранного кристалла. С помощью
электронных схем этот опорный сигнал можно умножить на небольшое целое число,
чтобы получить частоты до нескольких гигагерц или даже выше. В любом компьютере
можно найти как минимум одну такую схему, которая обеспечивает различные ком-
пьютерные электронные схемы синхросигналом. Этот сигнал поступает в счетчик, за-
ставляя его производить обратный отсчет до нуля. Когда значение счетчика становится
нулевым, он выдает прерывание на центральный процессор.
Рис. 5.24. Программируемые часы
У программируемых часов обычно бывает несколько режимов работы. В режиме одно-
кратного импульса
при запуске часы копируют значение регистра хранения в счетчик
и уменьшают это значение при получении каждого импульса с кварцевого генератора.
Когда значение счетчика станет нулевым, часы выдают прерывание и останавлива-
ются до тех пор, пока не будут запущены вновь программным способом. В режиме
прямоугольного импульса
после обнуления значения счетчика и выдачи прерывания
часы автоматически копируют значение регистра хранения в счетчик, и весь процесс
повторяется снова до бесконечности. Периодические прерывания называются тактом
системных часов
(clock ticks).
Преимущество программируемых часов в том, что частота выдаваемых ими преры-
ваний может управляться программным способом. При использовании кварцевого
генератора частотой 500 МГц импульсы на счетчик поступают каждые 2 нс. При ис-
5.5. Часы
437
пользовании 32-разрядных беззнаковых регистров прерывания могут быть запрограм-
мированы в интервале от 2 нс до 8,6 с. Микросхемы программируемых часов обычно
содержат двое или трое независимых друг от друга программируемых часов, а также
имеют множество других настроек (например, работа счетчика по нарастающей, а не
по убывающей, отключение прерываний и многое другое).
Чтобы текущее время не пропадало при отключении компьютера от источника пи-
тания, у многих компьютеров имеются резервные часы, запитанные от батарейки,
выполненные на микросхеме с пониженным энергопотреблением, используемой
в цифровых часах. Значение часов, питающихся от батарейки, может быть считано
при запуске компьютера. При отсутствии резервных часов программа может запросить
у пользователя ввод текущих даты и времени. Существует также стандартный способ,
применяемый в сетевых машинах, при котором текущее время берется у удаленной
главной машины. В любом случае после получения значения времени оно переводит-
ся в количество тактов системных часов, прошедшее с 12 часов дня универсального
скоординированного времени — UTC (Universal Coordinated Time) (ранее известного
как время по Гринвичу — Greenwich Mean Time) 1 января 1970 года, как это делается
в системах UNIX, или с какой-нибудь другой точки отсчета. Исходным временем для
Windows является 1 января 1980 года. С каждым тактом системных часов фактическое
время увеличивается на одно значение счетчика. Обычно служебные программы по-
зволяют вручную устанавливать значение системных и резервных часов и синхрони-
зировать их показания.
5.5.2. Программное обеспечение часов
Действие аппаратной составляющей часов ограничивается выдачей прерываний через
известные интервалы времени. Все остальное, касающееся времени, должно быть сдела-
но программным обеспечением — драйвером часов. Конкретные обязанности драйвера
часов варьируются в зависимости от используемой операционной системы, но чаще
всего в них включается практически всё из следующего списка:
1. Ведение показаний времени суток.
2. Предотвращение работы процессов дольше позволенного.
3. Ведение учета использования центрального процессора.
4. Обработка системного вызова alarm, выданного процессами пользователей.
5. Предоставление сторожевых программируемых таймеров для компонентов самой
операционной системы.
6. Ведение аналитического, мониторингового и статистического сбора информации.
Осуществление главной функции часов — ведения показаний времени суток (которое
также называется фактическим временем) не представляет особых трудностей. Нужно,
как упоминалось ранее, всего лишь увеличивать значение счетчика с каждым тактом
системных часов. Единственное, за чем нужно следить, — за количеством битов в счет-
чике времени суток. Если используются часы с частотой 60 Гц, то 32-разрядный счетчик
будет переполняться каждые два года. Понятно, что система не сможет хранить фак-
тическое время в виде числа тактов системных часов с 1 января 1970 года в 32 битах.
Эту проблему можно решить тремя способами. Первый способ предусматривает ис-
пользование 64-разрядного счетчика, хотя при этом усложняется его обслуживание,
438
Глава 5. Ввод и вывод информации
которое в течение секунды должно проводиться многократно. Второй способ заклю-
чается в ведении значения времени суток не в тактах, а в секундах с использованием
вспомогательного счетчика для подсчета тактов, пока не наберется целая секунда. По-
скольку 2
32
с — это более 136 лет, этот метод позволит системе работать до XXII века.
При третьем способе подсчет ведется в тактах, но делается он относительно времени
начальной загрузки системы, а не какого-то конкретного внешнего момента времени.
При считывании значения резервных часов или после ввода пользователем фактиче-
ского времени время начальной загрузки системы вычисляется из текущего времени
суток и сохраняется в памяти в удобной для системы форме. Чуть позже, когда будет
запрошено время суток, сохраненное время суток добавляется к счетчику, чтобы полу-
чить текущее время. Все три способа показаны на рис. 5.25.
Рис. 5.25. Три способа ведения значения времени суток
Вторая функция часов заключается в предотвращении излишне продолжительной
работы процессов. При каждом запуске процесса планировщик запускает его счетчик
кванта времени в тактах системных часов. При каждом прерывании от часов драйвер
часов уменьшает значение счетчика кванта времени на единицу. Когда значение дости-
гает нуля, драйвер часов вызывает планировщик для возобновления работы другого
процесса.
Третья функция часов — ведение учета использования центрального процессора.
Наиболее точно это можно сделать за счет запуска второго таймера, не имеющего от-
ношения к главному таймеру системы, при каждом запуске процесса. Когда процесс
останавливается, значение таймера может быть считано и по нему можно будет судить
о продолжительности работы процесса. Чтобы все работало должным образом, зна-
чение второго таймера должно быть сохранено при выдаче прерывания и после этого
восстановлено.
Менее точным, но более простым является способ ведения учета, при котором указа-
тель на запись в таблице процессов, относящуюся к текущему выполняемому процессу,
содержится в глобальной переменной. При каждом такте системных часов значение
поля в записи текущего процесса увеличивается на единицу. Таким образом, каждый
такт системных часов «отводится» тому процессу, который в этот момент выполняется.
Но при такой стратегии возникает небольшая проблема, которая заключается в том, что
если за время работы процесса возникает множество прерываний, ему все равно отво-
5.5. Часы
439
дится полный такт системных часов, даже если он и не проделал никакой существенной
работы. Строгий учет использования времени центрального процессора в условиях пре-
рываний его работы ведет к большим затратам ресурсов и применяется крайне редко.
Во многих системах процесс может запросить, чтобы операционная система спустя не-
который интервал времени выдавала ему предупреждение. В качестве предупреждения
обычно используется сигнал, прерывание, сообщение или что-либо подобное. Такое
предупреждение может быть использовано при сетевом обмене данными, где пакет, чье
получение не было подтверждено через определенный промежуток времени, должен
быть передан повторно. Другим применением может стать компьютеризированное
обучение, где студенту, не давшему ответ через определенное время, предоставляется
правильный ответ.
Если драйвер часов располагает достаточным количеством последних, то он может
выделить отдельные часы для каждого запроса. Но если их не хватает, он может
имитировать несколько виртуальных часов, используя лишь одни физические часы.
К примеру, он может вести таблицу, в которой содержится время выдачи сигнала для
всех поддерживаемых им не завершивших свою работу таймеров, а также переменную,
предоставляющую время срабатывания ближайшего таймера. При каждом обновлении
времени суток драйвер проверяет, не пора ли выдать очередной сигнал. Если уже пора,
в таблице ищется, куда его послать.
Если ожидается множество сигналов, то лучше будет сымитировать несколько часов,
выстроив в единую цепочку все невыполненные запросы на прерывание от таймера
и составив связанный список (рис. 5.26). Каждая запись списка сообщает, сколько
тактов системных часов следует ожидать за предыдущим тактом перед выдачей сигна-
ла. В данном примере ожидаются сигналы через 4203, 4207, 4213, 4215 и 4216 тактов.
Рис. 5.26. Имитация нескольких таймеров при использовании одних часов
На рис. 5.26 следующее прерывание выдается через 3 такта. С каждым тактом значе-
ние переменной Следующий сигнал уменьшается на единицу. Когда оно становится
равным нулю, выдается сигнал, соответствующий первому элементу списка, и затем
этот элемент из списка удаляется. Затем переменной Следующий сигнал присваивается
значение того элемента, который оказывается в начале списка, в данном примере это
значение равно четырем.
Обратите внимание на то, что при обработке прерывания от часов драйвер часов выпол-
няет массу задач — увеличивает показание фактического времени, уменьшает значение
кванта времени и проверяет, не равно ли оно нулю, ведет учет времени использования
центрального процессора и уменьшает значение сигнального счетчика. Но каждая из
этих операций должна быть оптимизирована на очень быстрое выполнение, поскольку
драйвер вынужден за одну секунду повторять их множество раз.
440
Глава 5. Ввод и вывод информации
Компоненты операционной системы также нуждаются в установке таймеров. Это
так называемые сторожевые таймеры, часто применяемые (особенно во встроенных
устройствах) для обнаружения таких проблем, как зависания. К примеру, сторожевой
таймер может перезапустить остановившуюся систему. В ходе работы системы таймер
регулярно перезапускается, поэтому срок его действия никогда не истекает. В данном
случае истечение времени таймера служит подтверждением того, что система не рабо-
тает долгое время, и это приводит к корректирующему действию, например к полному
перезапуску системы.
Механизм, используемый драйвером часов для обработки сторожевых таймеров, поч-
ти аналогичен обработке пользовательских сигналов. Единственное отличие состоит
в том, что когда время таймера истекает, вместо выдачи сигнала драйвер часов вы-
зывает процедуру, предоставленную обратившейся программой, частью кода которой
она и является. Процедура обратившейся программы может делать все, что ей нужно,
даже выдавать прерывание, хотя применение прерываний внутри ядра зачастую просто
мешает его работе, а сигналов там не существует. Именно поэтому и предоставляется
механизм сторожевых таймеров. Следует заметить, что этот механизм работает только
в том случае, когда драйвер часов и вызываемая процедура находятся в одном и том же
адресном пространстве.
Последним в нашем списке фигурирует сбор информации для профилирования
программ. Некоторые операционные системы предоставляют механизм, с помощью
которого пользовательская программа может иметь систему построения гистограмм от-
носительно показаний своего счетчика команд, чтобы можно было увидеть, на что рас-
ходуется ее время. Если такое профилирование возможно, то с каждым тактом драйвер
проверяет, профилируется ли текущий процесс, и, если он профилируется, вычисляет
номер ячейки суммирования (диапазон адресов), соответствующей текущему счетчику
команд. Затем значение этой ячейки увеличивается на единицу. Этот механизм может
быть использован также для профилирования самой системы.
5.5.3. Программируемые таймеры
Большинство компьютеров оборудовано вторыми программируемыми часами, которые
могут быть настроены на выдачу таймерных прерываний с любыми необходимыми
программе характеристиками. По отношению к таймеру основной системы, чьи функ-
ции были рассмотрены ранее, этот таймер является дополнительным. Пока частота
прерываний невысока, использование этого дополнительного таймера в прикладных
целях не вызывает никаких проблем. Трудности возникают при возрастании частоты
прерываний таймера, используемого в прикладных целях, до очень высоких значений.
Далее будет дано краткое описание схемы таймера, имеющего программную основу,
который справляется со многими обстоятельствами, даже с работой на очень высоких
частотах. Его идея принадлежит Арону и Дрюшелю (Aron and Druschel, 1999). Более
подробно она изложена в их статье.
Для управления вводом-выводом используются, как правило, два способа: прерывания
и опросы. Прерывания обладают небольшим временем задержки, то есть они проис-
ходят сразу же вслед за событием, с небольшой задержкой или вовсе без нее. В то же
время при использовании современных центральных процессоров прерывания приво-
дят к существенным издержкам в силу необходимости переключения контекста и их
влияния на конвейерную обработку, буфер TLB и кэш.