Дедупликация страницы исполняемого кода драйверов OC Windows (1187398), страница 8
Текст из файла (страница 8)
Следует учитывать только работу моего драйвера. И тотолько в моменты загрузки в систему нового драйвера. ...Было: N экземпляров по х. стр. Стало: 1 экземпляр из х страниц. Где N, это кол-водрайверов, а х - кол-во страниц одного экземпляра, имеющих тип NP, read-only.Вывод: Nx -> x.42(Кроме того, следует еще учесть размер моего драйвера.)2.3.1.3. Pageable readonly страницыБыло: N экземпляров по х страниц, находившихся в подкачиваемом пуле памяти.Значит, в зависимости от типа драйвера и интенсивности его работы кол-во страниц воперативной памяти могло меняться от 0 до Nx.
(и только низкие IRQL)Стало: (тоже, что и в предыдущем случае) 1 экземпляр из х страниц, нонаходящийся в неподкачиваемой памяти. Опять только чтение, значит, кол-во этихстраниц не меняется. То есть, их всегда будет ровно х.Мин оценка производительности моей программы (не нагруженный случай): 0 ->x.Макс: Nx -> x.Чтобы сделать вывод о полезности данного преобразования, нужно использоватьмат модель подкачки страниц. И по ней сделать выводы о том,Сколько страниц их Nx находятся в памяти в среднем.
(оценка занимаемойпамяти)Как часто происходит подкачка и отгрузка страниц. (нагрузка на процессор)При этом следует учитывать, что N наборов страниц независимые и одинаковые, астраница в них - х штук - могут быть зависимы (например, потому что нужны почтиодновременно, или из-за того, что оптимальный алгоритм подкачки страниц подкачиваетстраницы блоками).Вывод: необходимо найти мат модель подкачки страниц, определить среднее числостраниц в системе и уже их него делать выводы.2.3.1.4.
Pageable writable страницыБыло: тоже, что и в предыдущем случае. => min=0, max=Nx, и необходимоиспользовать мат модель подкачки страниц.Стало: 1 экземпляров из х страниц, и при запросах на запись выделяются новыестраницы.(Их всегда можно выделить, потому что данный код работает только при низкихIRQL. Это связано с тем, что изначально эти страницы были Pageable, а значит, создателидрайвера позаботились о том, чтобы этот код не вызывался при высоких IRQL.)В начале, страниц было ровно х, но во время работы драйверов при попыткахзаписи кол-во страниц увеличивается и может дойти до (N+1)x, если каждый драйвервыполнит запись во все свои страницы (все страницы каждого драйвера и плюс ещенулевой набор).43Кол-во страниц с записями в системе можно уменьшить, если:анализировать, одинаковые ли изменения драйверы в них производят иобъединять страницы с одинаковыми изменениями;измененные страницы обратно делать Pageable.Вывод:Минимальная выгода: 0 -> (N+1)x, то есть V = -(N+1)x.
(Когда драйверобращается к своим страницам очень редко, но при этом успел сделатьзапись в каждую страницу).Макс: Nx->x, V= +(N-1)x (когда драйвер постоянно использует своистраниц, но не пишет в них).Следует отметить, что, как правило, драйвер реально делает запись только внебольшое кол-во из своих х страниц кода. А остальные только читает и исполняет. Это связано с тем, что если даже запись происходит в одну страницу из секции, то как writeableпомечается все секция целиком.
(это касается только страниц кода)То есть : (0 ÷ N)x -> (1 ÷ N+1)xСледует создать и использовать мат модель разделения страниц с одной стороны имат модель подкачки/отгрузки страниц с другой стороны. И найти такие параметры N кол-во драйверов и х - кол-во Pageable writable страниц в них, при которых объединениетаких страниц будет выгодно.Что касается мат модели разделения страниц, то в данном случае важно толькообщее кол-во занимаемых страниц неподкачиваемой памяти, в то время как временныепоказатели (например, среднее время между разъединением страниц) отходят на второйплан.Нагрузка на процессор (во время работы системы) в этом случае существенноснижается, так как не нужно подгружать страницы с диска для операции чтения илиисполнения, которые происходят чаще чем операции записи. А те страницы, в которыепроисходит запись подгружаются лишь 1 раз.
Мин выгода: за все время - 0 (вообще неиспользуют эти страницы). Макс: t/(время подгрузки с диска + отгрузки 1й страницы) - 0(не пишут, но постоянно читают). Средняя же полезность определяется средним кол-вомстраниц, принадлежащих этим драйверам, подгружаемых с диска в минуту, из модельподкачки страниц.Нужно еще провести эксперименты с разными драйверами и выяснить в какое колво страниц из х на самом деле идет запись.442.3.1.5. NonPageable writable страницыБыло: ровно Nx страниц в неподкачиваемой памяти.Стало: (аналогично предыдущему случаю) сначала бал 1 набор из х страниц, но стечением времени, когда приходят запросы на запись страницы появляются новыестраницы, пока не разделятся все, которые только могут.
Максимальное число страниц впамяти в этом случае (N+1)x, где х - кол-во страниц этого типа в одном драйвере.Во-первых, это неподкачиваемый пул памяти, значит могут быть высокие IRQL.Это значит, что при попытке записи на страницу Copy On Write может оказатьсяневозможно выделить новую страницу для данного экземпляра драйвера.Поэтому рассмотрим 2 случая: отдельно низкие и высокие IRQL.2.3.1.5.1. Низкие IRQLВсегда можно выделять новые страницы памяти.
Тут все просто. Очень похоже напредыдущий случай. Мин: Nx->(N+1)x. Макс: Nx->x.Вывод: Собрать статистику кол-ва страниц (из NP writable), в которые на самомделе происходит запись. Nx->(1 ÷ N+1)x. И мат модель разделения страниц изпредыдущего случая.2.3.1.5.2. Высокие (IRQL ≥ Dispatch)С одной стороны нельзя выделять новые страницы, с другой стороны нельзяизменять код других драйверов или проигнорировать запрос на запись, что можетпривести к BSOD. Эта проблема решится, если заранее создать буфер страниц, и принеобходимости брать странички оттуда, пополняя его когда это возможно и необходимо.Итак, в этом случае в памяти находится еще и резервный буфер страниц.Мат модель для этого случая строится на основе мат модели разделения страниц изпредыдущего случая с учетом нового буфера и с акцентом на время между двумяпопытками записи.
Последнее особенно важно, так как именно тут оценивается размербуфера, а если его в какой-то момент не хватит, это приведет к временному зависаниюпотоков на высоких IRQL, что плохо отражается на надежности системы.Из данной мат модели будут получены оценки времени между событиями и исходяих них будет подкорректирован и размер и алгоритм пополнения резервного буферастраниц буфера.Кроме того, необходимо провести эксперименты с разными драйверами и выяснитьв какое кол-во страниц из х на самом деле идет запись.
Кроме того, можно сделать так,45чтобы мой драйвер при первом включении собирал статистику о кол-ве и частотеиспользования страниц, и исходя из этого корректировал размер буфера.2.3.1.6. ИтогИтак, рассмотрены все 4 типа страниц и их основные свойства и особенности,сведем информацию в одну таблицу для наглядности.read onlyNP (любые IRQL)P (low IRQL)1 тип.2 тип.Nx → x(0 ÷ N)x → xИзвестно точное кол-Мат модель подкачкиво страниц.writeableстраниц (№1).4 тип.3 тип.Nx → (1 ÷ N+1)x - MДополнительныйбуфер памяти из M страниц.Мат модельразделения страниц при(0 ÷ N)x → (1 ÷ N+1)xМат модель подкачкистраниц (№1) и мат модельразделениястраницпризаписи (№2) .записи (№2) с учетомвремени между событиями.Пример.Для иллюстрации полученных значений, приведем численные показатели.Допустим, в систему загружается 100 драйверов, пусть они имеют по 50, 30, 10 и 10страниц каждого типа, соответственно. И пусть, изначально из всех подкачиваемыхстраниц в памяти находилось 50%, размер подкачиваемого буфера выбирается из расчета6 страниц на драйвер.
Тогда, можем расcчитать выигрыш. Для первого типа: x*(N-1) =50*99 = 4950 страниц; для второго: x*50%*N - x = 30*50 - 30 = 1470; для третьего 7+(73)*100 = 407; для четвертого: 207. Итого, из всего 10 тысяч страниц, удалось сэкономитьчеть больше 7 тысяч. А это 70% и 27 Мб.Итак, рассмотрев 4 типа памяти приходим к необходимости учета двух различныхмат моделей. Рассмотрим их подробнее.462.3.3.
Математическая модель разделения страниц при записи (Модель №2).Математическая модель разделения страниц при записи (№2) с учетом временимежду событиями.2.3.3.1. Основные положенияПусть в начальный момент времени в виртуальной памяти было N экземпляровдрайвера по L станиц, которые отображались на один "нулевой" набор из L страниц вфизической памяти. Экземпляры считаем одинаковыми и независимыми, а страницы изодного набора - различными и, возможно, не независимыми друг от друга. Это связано стем, что драйвер может в одной своей функции сделать записи в несколько своих страниц,например, идущих подряд.
Для моей системы это будет выглядеть как несколькопоследовательных, но очень близких по времени, запросов на запись (то есть вызововMyMmAccessFault). Таким образом запись в первую из этих страниц будет автоматическиозначать и запись во все остальные.Пусть в некоторый момент времени t приходит запрос на запись в j-ю страницу iтого набора - write(i, j). Тогда вызывается моя функция MyMmAccessFault, происходитвыделение новой страницы (или взятие из буфера при высоких IRQL), и расщеплениестраниц. Таким образом, для i-го набора j-ая виртуальная страница ссылается теперь не нааналогичную копируемую при записи страницу из "нулевого" набора, а на своюотдельную доступную для записи физическую страницу.
Дальнейшие запросы на запись вэту страницу никак не влияют на работу остальной системы и не будут приводить кнарушениям прав доступа, и вызовам MmAccessFault, следовательно, в данной моделимогут не учитываться.Краткий итог - характеристика модели: существуют N одинаковых независимыхэкземпляров, содержащих L различных не независимых страниц; кроме того, важентолько первый вызов write(i,j) для каждого iϵ [1,N] и jϵ [1,L].2.3.3.2.Простейшийслучай:1драйвери1страница. Обоснованиеприменимости.Раз экземпляры одинаковы и независимы, можно рассмотреть сначала поведениеодного из них, а потом обобщить это на N штук.47Поскольку страницы не независимы, и связь между ними (их корреляция)изначально не известна, построить математическую модель довольно сложно. Однако, изэтого затруднения можно выйти, построив программу специфическим образом:а) для случая Pageable Writable страниц, где важно среднее кол-во страниц всистеме, можно провести ряд экспериментов для каждого драйвера и найти m =выборочное среднее кол-ва страниц, в которые ведется запись за один вызов функциидрайвера, то есть которые требуется разъединить почти одновременно.
Потом построитьмат модель для L' независимых страниц и умножить ее на это выборочное среднее. L'определяется из формулы L/m. Кроме того, надо проверить данную гипотезу; то естьпостроить модель и подставить, возможно, для случая где важно лишь общее кол-востраниц это не важно.б) для случая NonPageable Writable страниц при высоких IRQL, где наоборот,важнее время между вызовами, можно просто сделать отдельный буфер для каждойстранички и рассматривать их отдельно, а пополнение сделать раз в определенное время,например, равное мат ожиданию времени между двумя соседними вызовами. или простоувеличить размер буфера страниц в m раз, где m= выборочное среднее кол-ва страниц, вкоторые ведется запись за один вызов функции драйвера, то есть которые требуетсяразъединить почти одновременно.Страницы драйвера не являются независимыми.