ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 03.02.2024
Просмотров: 41
Скачиваний: 0
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
Средняя загруженность при обработке прерываний — 82%.
Оставшиеся 8% (90% — 82% = 8%) используются планировщиком.
В течение последних 60 секунд загруженность процессора составила 60%, а средняя загруженность в течение пяти минут — 40%. Из индивидуальной для каждого процесса информации видно, что в течение последних пяти секунд 8?% процессорных ресурсов было занято процессом ip_input. Нулевые значения показателей загруженности означают, что процесс не имел возможности выполняться в промежутке соответствующего интервала либо значение загруженности составляло меньше 0,01%. Из приведенного выше примера видно, что довольно-таки большой процент процессорных ресурсов приходится на обработку прерываний. Возникает вопрос: чем же занимается операционная система IOS в течение 82% своего рабочего времени? К сожалению, система не предоставляет детальной информации об обработке процессором прерываний, как это сделано для процессов; посему трудно привязать загруженность процессора к конкретной задаче. Однако можно сделать предположение относительно использования процессорных ресурсов.
Как вы узнаете в главе , “Принципы коммутации пакетов”, при использовании механизма быстрой коммутации (fast switching) пакетов львиная доля работы выполняется именно на уровне обработки прерываний. Операционная система IOS также выполняет и другую работу, обрабатывая прерывания, однако большая часть времени все же тратится на коммутацию пакетов. Посему высокое значение загруженности процессора обычно означает, что системе IOS приходится заниматься коммутацией большого количества сетевых пакетов. Незадействованное процессорное время (10% в нашем примере) носит название времени холостого хода или простоя. “Время простоя”, однако, не совсем точное определение, поскольку процессор на самом деле никогда не простаивает: в нем постоянно выполняются какие-то инструкции (машинные команды). В системе IOS время простоя в действительности означает, что ресурсы процессора используются собственно планировщиком (а это весьма важный процесс в системе). Очень важно, чтобы у операционной системы IOS было достаточно времени холостого хода. При приближении загруженности процессора к 100% на нужды планировщика практически не остается ресурсов, что приводит к весьма серьезным последствиям. Поскольку планировщик отвечает за выполнение всех фоновых критичных процессов, нехватка процессорных ресурсов может привести к отказу системы.
Cистема IOS располагает так называемым сторожевым таймером, который предотвращает тотальную загруженность центрального процессора. К сожалению, операционная система IOS не всегда применяет этот механизм защиты для прерываний. Хотя многие платформы и поддерживают ограничение на использование ресурсов центрального процессора через так называемые заглушки прерываний, по умолчанию данная функция отключена. В любом случае сторожевые таймеры и заглушки прерываний — это всего лишь механизмы безопасности. Когда система планируется для высокоскоростной обработки пакетов (например, если в систему встроено большое количество сетевых интерфейсов, подключенных к загруженным каналам), рациональнее выбрать более производительный процессор и настроить систему на использование наиболее эффективного механизма коммутации для избежания перегрузки центрального процессора.
Сторожевой таймер.
Для уменьшения риска перегруженности процессора операционная система IOS устанавливает сторожевой таймер для процессов, который позволяет планировщику периодически ограничивать выполнение текущего процесса. Не следует пугать этот механизм с преемптивной многозадачностью, поскольку он является всего лишь средством защиты системы от перегруженности и полной блокировки при тотальном занятии процессом процессорных ресурсов. Если процесс в системе окажется подвешенным (например, выполняющимся неоправданно долго), планировщик может остановить его выполнение.
Каждый раз, когда планировщик предоставляет процессу возможность выполняться, запускается сторожевой таймер для этого процесса. По истечении заданного промежутка времени (по умолчанию 2 секунды), если процесс все еще выполняется, то управление передается обратно планировщику. После первого срабатывания сторожевого таймера планировщик выводит предупреждающее сообщение и продолжает выполнение процесса. Если сторожевой таймер срабатывает во второй раз, а процесс все еще не приостанавливается, планировщик останавливает выполнение процесса.
Менеджер памяти.
Менеджер памяти ядра несет ответственность на макроуровне за управление всей доступной памятью операционной системы IOS, включая и память, содержащую собственно выполняемый код системы IOS. Менеджер памяти в действительности не единичный компонент и состоит из трех отдельных модулей, каждый из которых отвечает за свои задачи, которые перечислены ниже.
Менеджер областей памяти — выделяет и поддерживает различные области памяти для данной платформы.
Менеджер пулов памяти — управляет созданием пулов памяти, выделением и освобождением отдельных блоков внутри пулов.
Менеджер фрагментов памяти — управляет специально выделенными блоками памяти, содержащими несколько фрагментов фиксированного размера.
Менеджер областей памяти.
Менеджер областей памяти отвечает за поддержание всех существующих областей. Он предоставляет услуги другим частям операционной системы IOS создавать отдельные области и устанавливать их атрибуты. Менеджер областей также позволяет организовывать запросы для получения информации о доступных областях (например, для определения общего объема доступной памяти).
Менеджер пулов памяти.
Менеджер пулов памяти является весьма важным компонентом системы. Так же как планировщик отвечает за предоставление процессам ресурсов центрального процессора, менеджер пулов памяти предоставляет процессам возможность выделения памяти. Для выделения памяти под собственные нужды процесс должен напрямую или косвенно обратиться к менеджеру пулов памяти. Менеджер пулов отрабатывается каждый раз, когда процесс вызывает стандартные системные вызовы malloc или free для выделения и освобождения памяти соответственно. Вся работа менеджера пулов памяти опирается на использование списка свободных блоков памяти внутри каждого пула. Очевидно, что изначально каждый пул содержит по одному большому блоку свободной памяти, размер которого равен размеру пула. В процессе обработки запросов к памяти начальный свободный блок памяти становится все меньше и меньше. В то же время процессы могут освобождать занятые блоки памяти. Таким образом, в ходе работы системы образуется несколько блоков свободной памяти, отличающихся по своим размерам (рис. 1.5). Данное явление носит название фрагментация памяти (memory fragmentation).
Рис. 1.5.
После того как освобожденный блок памяти будет возвращен в пул, менеджер добавляет размер и начальный адрес данного блока в один из списков сходных по размерам свободных блоков. По умолчанию менеджер пулов поддерживает списки для следующих размеров блоков.
Когда процесс требует выделения памяти, менеджер пулов сначала просматривает список свободных блоков необходимого размера. Этот механизм позволяет более эффективно использовать свободную память за счет близких по размеру блоков памяти. Если в списке блоков подходящего размера не найдено свободных блоков, менеджер переходит к рассмотрению списка блоков большего размера, до тех пор, пока подходящий блок не будет найден. Если менеджеру приходится использовать блок большего размера, чем было запрошено, найденный блок расщепляется и свободная его часть помещается в соответствующий список свободных блоков меньшего размера.
Менеджер пулов памяти пытается контролировать фрагментацию памяти путем объединения рядом расположенных свободных блоков. Когда блок памяти освобождается, менеджер просматривает память на предмет наличия за освобожденным блоком свободной области. Если такая область найдена, то блоки объединяются в один с последующим размещением его в соответствующий список свободных блоков памяти (рис. 1.6).
Рис. 1.6.
Выше мы рассматривали результат работы команды show memory, выводящей имена и различную информацию о пулах памяти, а также детальную информацию о каждом блоке памяти внутри пулов. Вывод команды show memory содержит список всех блоков памяти, включенных в соответствующие пулы (пример 1.6.)
Пример 1.6.
Описание полей из примера 1.6.
Address — поле начального адреса блока.
Bytes — размер блока.
Prev — адрес предшествующего блока.
Next — адрес следующего блока.
Ref — число владельцев данного блока.
PrevF — адрес предыдущего блока в списке свободных блоков (только для свободных блоков).
NextF
— адрес следующего блока в списке свободных блоков (только для свободных блоков).
Alloc PC — значение регистра счетчика команд на момент выделения данного блока. Это значение позволяет определить, какой процесс выделил данный блок памяти.
What — описание использования блока.
Можно использовать модификацию команды show memory free для отображения свободных блоков в каждом пуле памяти (пример 1.7).
Пример 1.7.
Вывод команды содержит перечень свободных блоков в порядке списков свободных блоков. Пустые списки свободных блоков отображаются без последующей информации о блоках памяти.
Менеджер фрагментов.
Менеджер пулов предоставляет довольно эффективный способ организации блоков памяти разного размера. Однако это не дается даром: для каждого такого блока памяти приходится использовать 32 байта служебной информации. Конечно, для пулов с небольшим количеством блоков большого размера на служебную информацию тратится весьма малый объем памяти. Однако для пулов, содержащих несколько тысяч маленьких блоков, такая расточительность менеджера пулов становится неоправданной. Как вариант решения возникшей проблемы, ядро предоставляет так называемый менеджер фрагментов (chunk manager), который обслуживает большие пулы с большим количеством маленьких блоков. При этом память не расходуется на служебную информацию для каждого блока.
В отличие от менеджера пулов памяти, менеджер фрагментов не оперирует со списками свободных блоков. Вместо этого он разбивает большой блок памяти, выделенный из одного из пулов, на множество фрагментов одинакового размера. В некотором роде работа менеджера фрагментов аналогична работе менеджера пулов, только все операции с фрагментами выполняются в пределах одного пула. В общем случае механизм работы с памятью выглядит следующим образом: процесс запрашивает выделение большого блока памяти из определенного пула. Затем процесс обращается к менеджеру фрагментов для разделения этого блока на несколько фрагментов фиксированного размера и последующего выделения отдельных фрагментов. Преимущество такого подхода состоит в том, что служебная информация (32 байта) связана с большим блоком памяти, а менеджеру пулов не приходится выделять множество маленьких кусочков памяти. Таким образом, удается заметно снизить фрагментацию пула памяти.