Реферат: Разработка операционных систем
Производительность
При прочих равных
условиях быстрая операционная система лучше медленной. Однако быстрая, но
ненадежная операционная система хуже надежной, но медленной. Поскольку сложные
оптимизирующие методы часто приводят к появлению в системе новых ошибок, не
следует злоупотреблять оптимизацией. И все же существуют области, в которых
производительность является критичной и оптимизация стоит затрачиваемых усилий.
В следующих разделах мы рассмотрим несколько общих методов, которые могут
применяться для повышения производительности там, где это нужно.
Кэширование
Хорошо известным методом
повышения производительности является кэширование. Оно может применяться каждый
раз, когда с большой вероятностью можно предсказать, что много раз потребуется
один и тот же результат. Общий метод заключается в том, чтобы выполнить всю
работу в первый раз, а затем сохранить результат в кэше. При последующих
попытках в первую очередь будет проверяться кэш. Если результат находится в
кэше, то нужно всего лишь достать его оттуда. В противном случае необходимо
проделать всю работу сначала.
Мы уже наблюдали
использование кэша в файловой системе, где он хранит некоторое количество
недавно использовавшихся блоков диска, что позволяет избежать обращения к диску
при чтении блока. Однако кэширование может также применяться и для других
целей. Например, обработка путей к файлам отнимает удивительно много процессорного
времени. Рассмотрим снова пример из системы UNIX.Чтобы найти файл
/usr/ast/mbox, потребуется выполнить следующие обращения к диску:
1. Прочитать i-узел
корневого каталога (i-узел 1).
2. Прочитать корневой
каталог (блок 1).
3. Прочитать i-узел
каталога /usr (i-узел 6).
4. Прочитать каталог /usr
(блок 132).
5. Прочитать i-узел
каталога /usr/ast (i-узел 26).
6. Прочитать каталог
/usr/ast (блок 406).
Чтобы просто определить
номер i-узла искомого файла, нужно как минимум шесть раз обратиться к диску. Если
размер файла меньше размера блока (например, 1024 байт), то, чтобы прочитать
содержимое файла, нужно восемь обращений к диску.
В некоторых операционных
системах обработка путей файлов оптимизируется при помощи кэширования пар
(путь, i-узел).
Когда файловая система
должна найти файл по пути, обработчик путей сначала обращается к кэшу и ищет в
нем самую длинную подстроку, соответствующую обрабатываемому пути. Если
обрабатывается путь /usr/ast/grants/stw, кэш отвечает, что номер i-узла
каталога /usr/ast равен 26, так что поиск может быть начат с этого места и
количество обращений к диску может быть уменьшено на четыре. Недостаток
кэширования путей состоит в том, что соответствие имени файла номеру его i-узла
не является постоянным. Представьте, что файл /usr/ast/mbox удаляется и его
i-узел используется для другого файла, владельцем которого может быть другой
пользователь. Затем файл /usr/ast/mbox создается снова, но на этот раз он
получает i-узел с номером 106. Если не предпринять специальных мер, запись кэша
будет указывать на неверный номер i-узла. Поэтому при удалении файла или
каталога следует удалять из кэша запись, соответствующую этому файлу, а если
удаляется каталог, то следует удалить также все записи для содержавшихся в этом
каталоге файлов и подкаталогов*.
Кэшироваться могут не
только блоки дисков и пути к файлам. Можно кэшировать также i-узлы. Если для
обработки прерываний используются временные потоки, для каждого из них
требуется стек и некоторый дополнительный механизм. Эти использовавшиеся ранее
потоки также можно кэшировать, так как обновить уже использовавшийся поток
легче, чем создать новый (применение кэша позволяет избежать необходимости в
выделении новому процессу памяти). Кэширование может применяться почти для
всего, что трудновоспроизводимо.
Подсказки
Элементы кэша всегда
должны быть корректны. Поиск в кэше может завершиться неудачей, но если элемент
найден, то его корректность гарантируется, поэтому найденный элемент может
использоваться без дополнительных хлопот. В некоторых системах бывает удобным
содержать таблицу подсказок. Подсказки представляют собой предложения решений,
но их корректность не гарантируется. Обращающийся к этой таблице процесс должен
сам проверять корректность результата.
Хорошо известным примером
подсказок являются указатели URL, содержащиеся в web-страницах. Когда
пользователь щелкает мышью на ссылке, он не получает гарантии, что
соответствующая web-страница находится там, куда указывает URL. В самом деле,
может оказаться, что требующаяся страница удалена несколько лет назад. Таким
образом, информация, содержащаяся на web-странице, представляет собой всего
лишь подсказку.
Подсказки также
используются при работе с удаленными файлами. Информация, содержащаяся в
подсказке, сообщает нечто об удаленном файле, например его местонахождение.
Однако, возможно, этот файл уже удален или перемещен в другое место, поэтому
всегда требуется проверка корректности подсказки.
Использование локальности
Процессы и программы
действуют не случайным образом. Они оказываются в значительной степени
локальными как во времени, так и в пространстве, и эта информация может быть
использована различными способами для улучшения производительности. Один хорошо
известный пример пространственной локальности заключается в том факте, что процессы
не прыгают произвольным образом в пределах своего адресного пространства. Как
правило, за фиксированный интервал времени они используют относительно
небольшое количество страниц. Страницы, активно используемые процессом, могут
рассматриваться как рабочий набор процесса. А операционная система может
гарантировать, что этот рабочий набор находится в памяти, когда процесс
получает управление, тем самым снижается количество страничных прерываний.
Принцип локальности также
применим для файлов. Когда процесс выбирает конкретный рабочий каталог, многие
из его последующих файловых обращений, скорее всего, будут относиться к файлам,
расположенным в этом каталоге Производительность можно повысить, если поместить
все файлы каталога и их i-узлы близко друг к другу на диске. Именно этот
принцип лежит в основе файловой системы Berkeley Fast File System .
Другой областью, в
которой локальность играет важную роль, является планирование потоков в
мультипроцессорах. Как было показано в главе 8, один из методов планирования
потоков заключается в том, чтобы попытаться запустить каждый поток на том
центральном процессоре, на котором он работал в прошлый раз, в надежде, что
какие-нибудь из его блоков все еще находятся в кэше.
Оптимизируйте общий
случай
Часто бывает полезно
различать наиболее частый случай и наименее вероятный случай и обращаться с
ними по-разному. Обычно различные случаи обрабатываются совершенно различными
программами. Важно, чтобы частый случай работал быстро. От алгоритма для редко
встречающегося случая достаточно добиться корректной работы.
В качестве первого
примера рассмотрим вхождение в критическую область. В большинстве случаев
процессу будет удаваться вход в критическую область, особенно если внутри этой
области процессы не проводят много времени. Операционная система Windows 2000
использует это преимущество, предоставляя вызов Win32 API EnterCriticalSection,
который является атомарной функцией, проверяющей флаг в режиме пользователя (с
помощью команды процессора TSL или ее эквивалента). Если тест проходит успешно,
процесс просто входит в критическую область, для чего не требуется обращения к
ядру. Если же результат проверки отрицательный, библиотечная процедура
выполняет на семафоре операцию down, чтобы заблокировать процесс. Таким
образом, в нормальном случае обращение к ядру не требуется.
В качестве второго
примера рассмотрим установку будильника (использующего сигналы UNIX). Если в
текущий момент ни один будильник не заведен, то просто создается запись и
помещается в очередь таймеров. Однако если будильник уже заведен, его следует
найти и удалить из очереди таймера. Так как системный вызов alarm не указывает,
установлен ли уже будильник, система должна предполагать худшее, то есть что он
уже заведен. Однако в большинстве случаев будильник не будет заведен, и
поскольку удаление существующего будильника представляет собой дорогое
удовольствие, то следует различать эти два случая.
Один из способов
достижения этой цели заключается в том, чтобы хранить бит в таблице процессов,
указывающий, заведен ли будильник. Если бит сброшен, то программа следует по
простому пути (просто добавляется новая очередь таймера без какой-либо
проверки). Если бит установлен, то очередь таймера требует проверки.
Управление проектом
Многие программисты
являются вечными оптимистами. Они полагают: чтобы написать программу, нужно
всего лишь поскорее сесть за клавиатуру и начать набивать символы. Вскоре после
этого появится полностью законченная отлаженная программа. Очень большие
программы таким способом написать невозможно. В следующих разделах мы кратко
обсудим вопросы управления большими программными проектами, особенно управления
большими системными проектами.
Мифический человеко-месяц
В своей классической
книге Фред Брукс, один из разработчиков системы OS/360, занявшийся впоследствии
научной деятельностью, рассматривает вопрос, почему так трудно построить
большую операционную систему [44, 46]. Когда большинство программистов
встречаются с его утверждением, что специалисты, работающие над большими
проектами, могут за год произвести всего лишь 1000 строк отлаженного кода, они
удивляются, не прилетел ли профессор Брукс из космоса, с планеты Баг. В конце
концов, большинство из них помнит, как они создавали программу из 1000 строк
всего за одну ночь. Как же этот объем исходного текста может составлять годовую
норму для любого программиста, чей IQ превышает 50?
Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 |