Почему Windows откладывает создание PPTE для файлов данных? - PullRequest
1 голос
/ 09 апреля 2019

FSD вызывает CcInitializeCacheMap при первом чтении / записи в файл, что приведет к созданию карты частного кэша, объекта раздела, области управления, сегмента, подразделов, если они еще не существуют. Когда менеджер кэша создает объект раздела, он указывает, что это раздел данных SEC_DATA в параметре sectionattributes NtCreateSection, что означает, что PPTE изначально не настроены, а база в сегменте оставлена ​​пустой. Фактическое чтение выполняется с использованием CcCopyRead, который сначала выделяет VACB и отображает представление файла, а затем копирует из VACB в буфер. Каждый раз, когда он выделяет VACB, он отображает представление размером 265 КБ в виртуальное пространство диспетчера кэша. Когда он делает это отображение, ему нужно инициализировать PPTE, но когда он инициализирует один PPTE, он может также инициализировать их все для всего файла, потому что они должны быть смежными по своему дизайну; эта память будет зарезервирована независимо от того, выделены они или нет.

Внутренние компоненты Windows утверждают, что откладывают создание PPTE для файлов данных до тех пор, пока не будет отображено первое представление, но с файлами изображений он создает их при создании объекта раздела.

Для разделов на основе файла подкачки массив прототипных PTE создается при первом создании объекта раздела. Для сопоставленных файлов части массива создаются по требованию при сопоставлении каждого представления.

И еще один источник утверждает:

При отображении файла данных основное назначение MiCreateDataFileMap - настроить объект подраздела. В обычном случае создается только один подраздел, но при некоторых особых условиях используются несколько подразделов, например если файл очень большой. Для файлов данных поле подраздела SubsectionBase оставлено пустым. Это откладывает создание PPTE до тех пор, пока раздел не будет отображен в память и, наконец, не будет доступен первый раз. Причина этого заключается в том, чтобы не тратить память при отображении очень больших файлов данных. Вместо этого поле SegmentPteTemplate объекта сегмента настроено правильно, что может использоваться для последующего создания PPTE при необходимости.

Я просто не согласен с этим, потому что, если бы был сопоставлен файл данных 4 ГБ, потребовалось бы всего 2 МБ страниц PPTE, что не так много места, поэтому я не вижу в этом пользы. Реальная экономия места достигается за счет VACB и того факта, что весь файл не должен находиться в физической памяти.

По-прежнему не имеет смысла, почему они утверждают, что «части» PPTE инициализируются по требованию, как будто это подразумевает экономию места, потому что это не происходит, потому что, как только один PPTE отображается, вся область резервируется и SubsectionBase установлено в сегменте, так как PPTE для всего файла должны быть смежными.

'порции' могут быть инициализированы по требованию, но это не меняет того факта, что пространство зарезервировано независимо от того, есть ли там PPTE или нет. Например, когда выделяется VACB, он может инициализировать все PPTE, охватывающие 256 КБ. Когда происходит сбой страницы, PTE указывают на PPTE, и эти PPTE будут недействительными, поэтому он может выполнять кластерный ввод 256 КБ с гранулярностью 256 КБ, что означает, что любые другие ошибки страницы будут ошибкой мягкой страницы. (Я полагаю, что когда PPTE выделяются в первый раз, в то время, когда PTE выделяются для представления VACB, PTE создаются для указания на PPTE. Внутренние компоненты Windows приводят некоторые недоразумения по поводу ошибочного виртуального адреса, используемого для поиска VAD процесс запуска и окончания PPTE на стр. 411, но системный кеш является частью памяти ядра, которая не отслеживается VAD, поэтому он ошибочен. Этот метод используется только для отображения пространства пользователя). Проблема, связанная с этим, заключается в том, что страница может быть изменена, поэтому она не обязательно может выполнить оптимизацию кластера 256 КБ (1 ошибка жесткого диска, 63 программного обеспечения) и заблокировать страницы в памяти для выполнения ввода-вывода. Он должен был бы знать, что все PPTE заново распределены, и ошибка не только в том, что не было ни одного кадра. Лучше всего было бы выполнить ввод-вывод, когда представления в диапазоне сопоставлены, и PPTE выделен, так что при чтении не произойдет сбоя страницы. В противном случае пришлось бы обслуживать 64 жестких сбоев страниц.

Так какой смысл? Он также может инициализировать массив PPTE, как только будет создан раздел файла данных, поскольку он будет немедленно прочитан только в сценарии выше. Я не могу придумать сценарий, когда процесс отобразит загрузку файлов в свое адресное пространство, а затем не коснется их. Даже если бы он отображал 40 ГБ, он все равно занимал бы только 20 МБ в PPTE, поскольку они были инициализированы при создании раздела данных.

1 Ответ

0 голосов
/ 09 апреля 2019

Полагаю, преимущество заключается в том, что зарезервированный виртуальный диапазон, который будет содержать PPTE, фактически не отображается на физическую память, несмотря на то, что весь диапазон PPTE в виртуальном пространстве будет использоваться для каждого процесса.Когда сопоставляется VACB, будет заполнена часть PPTE для диапазона, которая теперь имеет стоимость в физической памяти.Это все еще только 20 МБ для файла 40 ГБ.20 МБ будет зарезервировано в виртуальной памяти, а 0 - в физической.Объем занимаемого физического пространства увеличился бы на 64 * 8 байт на просмотр 256 КБ.

...