3.Внутреннее устройство Windows (гл. 8-11)
Шрифт:
Если подсистема отложенной записи должна записать на диск данные из представления, проецируемого и на адресное пространство другого процесса, ситуация несколько усложняется. Дело в том, что диспетчеру кэша известны лишь страницы, модифицированные им самим. (O страницах, модифицированных другим процессом, знает только этот процесс, так как биты изменения этих страниц находятся в элементах таблиц страниц, принадлежащих исключительно процессу.) Чтобы справиться с этой ситуацией, диспетчер памяти посылает диспетчеру кэша соответствующее уведомление в тот момент, когда пользователь проецирует какой-либо файл. При сбросе такого файла из кэша (например, в результате вызова Windows-функции FlushFileBuffers) диспетчер
1. Пользователь удаляет проекцию представления.
2. Процесс сбрасывает файловые буферы.
При ином порядке событий предсказать, какие страницы будут записаны на диск, нельзя.
ЭКСПЕРИМЕНТ: наблюдение за операциями сброса кэша
Вы можете увидеть, как диспетчер кэша проецирует представления в системный кэш и сбрасывает страницы на диск, запустив оснастку Performance (Производительность) и добавив счетчики Data Maps/sec (Отображений данных/сек) и LazyWrite Flushes/sec (Сбросов ленивой записи/сек), а затем скопировав большой файл из одного места в другое. Ha следующей иллюстрации показаны графики, относящиеся к Data Maps/sec (верхний) и к LazyWrite Flushes/sec (нижний).
Файловая система и диспетчер кэша должны определять, повлияет ли запрос кэшированной записи на производительность системы, и исходя из этого планировать отложенные операции записи. Сначала файловая система через функцию CcCanIWrite выясняет у диспетчера кэша, можно ли записать определенное число байтов прямо сейчас без ущерба для производительности, и при необходимости блокирует запись. Далее она настраивает обратный вызов диспетчера кэша для автоматической записи данных на диск, когда запись вновь будет разрешена вызовом CcDeferWrite. Получив уведомление о предстоящей операции записи, диспетчер кэша определяет, сколько измененных страниц находится в кэше и какой объем физической памяти доступен. Если свободных физических страниц мало, диспетчер кэша немедленно блокирует поток файловой системы, выдавший запрос на запись данных в кэш. Подсистема отложенной записи сбрасывает часть измененных страниц на диск, после чего разрешает продолжить выполнение блокированного потока файловой системы. Такой механизм, называемый дросселированием записи (write throttling), предотвращает падение быстродействия системы из-за нехватки памяти при операциях записи большого объема данных, инициируемых файловой системой или сетевым сервером.
ПРИМЕЧАНИЕ Дросселирование записи оказывает глобальное влияние на систему, так как ресурс, на котором основан этот механизм, — свободная физическая память — является глобальным. И если интенсивная запись на медленное устройство вызывает дросселирование, это распространяется на операции записи и на другие устройства.
Пороговое число измененных страниц (dirty page threshold) — это количество страниц, хранимых системным кэшем в памяти, по достижении которого пробуждается поток подсистемы отложенной записи для сброса страниц на диск. Это значение вычисляется при инициализации системы и зависит от объема физической памяти и параметра реестра LargeSystemCache, как мы уже объясняли.
Алгоритм расчета порогового числа измененных страниц представлен в таблице 11–13. Результат расчета с использованием этого алгоритма игнорируется, если максимальный размер системного рабочего набора превышает 4 Мб, — а именно так зачастую и происходит. (Определение малого, среднего и большого объема системной памяти см. в главе 7.) Когда максимальный размер рабочего
набора превышает 4 Мб, пороговое число измененных страниц устанавливается равным максимальному размеру системного рабочего набора за вычетом 2 Мб.Дросселирование записи также полезно для сетевых редиректоров, передающих данные по медленным коммуникационным каналам. Вообразите, например, локальный процесс, записывающий большой объем данных в удаленную файловую систему по каналу, работающему со скоростью 9600 бод. Данные не попадут на удаленный диск, пока подсистема отложенной записи диспетчера кэша не сбросит кэш на диск. Если редиректор накапливает много измененных страниц, одновременно сбрасываемых на диск, на принимающей стороне может истечь время ожидания данных до окончания их передачи. Развитие событий по такому сценарию можно предотвратить с помощью функции диспетчера кэша CcSetDirtyPageTbresbold, позволяющей сетевым редиректорам устанавливать лимит на количество измененных страниц, которые можно накапливать без сброса на диск. Ограничивая число измененных страниц, редиректор гарантирует, что операции сброса кэша не вызовут таймаута.
ПРИМЕЧАНИЕ B Windows XP и выше сетевые редиректоры не задают пороговое значение измененных страниц, вместо этого полагаясь на системные значения по умолчанию.
ЭКСПЕРИМЕНТ: просмотр параметров дросселирования записи
Команда !defwrites отладчика ядра выводит дамп значений переменных ядра, используемых диспетчером кэша для определения момента дросселирования операций записи.
Как видите, число измененных страниц близко к пороговому значению, при котором начинается дросселирование записи (CcDirtyPageTbreshold), и поэтому, если бы в ходе эксперимента процесс попытался записать более 12 страниц (48 Кб), эти операции были бы отложены до тех пор, пока подсистема отложенной записи не уменьшила бы число измененных страниц.
Как уже говорилось, диспетчер кэша выполняет отложенную запись и опережающее чтение, передавая запросы в общий пул критичных системных рабочих потоков. Однако в системах с малым и средним объемом памяти он использует на один поток меньше общего количества критичных системных рабочих потоков, а в системах с большим объемом памяти — на два.
Внутренне диспетчер кэша организует свои запросы в два списка (которые все равно обслуживаются одним и тем же набором рабочих потоков исполнительной системы):
• экспресс-очередь (express queue) — для операций опережающего чтения;
•регулярная очередь (regular queue) — для отложенной записи измененных данных, подлежащих сбросу, обратной записи и отложенного закрытия файлов.
Чтобы отслеживать рабочие элементы, направленные рабочим потокам, диспетчер кэша создает собственный ассоциативный список (индивидуальный для каждого процессора и имеющий фиксированную длину) структур рабочих элементов, поставленных в очереди рабочих потоков (ассоциативные списки обсуждаются в главе 7). Число элементов в очереди рабочего потока определяется объемом системной памяти и для систем Windows Professional составляет 32,64 или 128 в системах с малым, средним или большим объемом памяти соответственно (для систем Windows Server с большим объемом памяти — 256).
Диспетчер кэша предоставляет быстродействующий интеллектуальный механизм для уменьшения интенсивности дискового ввода-вывода и увеличения общей пропускной способности системы. Осуществляя кэширование на основе виртуальных блоков, диспетчер кэша может выполнять интеллектуальное опережающее чтение. Используя для обращения к файловым данным механизм проецирования файлов, диспетчер кэша предоставляет специальный механизм для быстрого ввода-вывода, который уменьшает нагрузку на процессор при выполнении операций чтения и записи и позволяет возложить все управление физической памятью на диспетчер памяти. A это избавляет от дублирования кода и повышает эффективность работы операционной системы.