Почему ядро ​​обеспокоено выпуском ФИЗИЧЕСКИ смежных страниц? - PullRequest
10 голосов
/ 14 ноября 2011

Когда процесс запрашивает страницы физической памяти у ядра Linux, ядро ​​делает все возможное, чтобы предоставить блок страниц, которые физически непрерывны в памяти. Мне было интересно, почему это важно, что страницы физически смежны; в конце концов, ядро ​​может скрыть этот факт, просто предоставляя страницы, которые ВИРТУАЛЬНО смежны.

И все же ядро, конечно, изо всех сил старается предоставить страницы, которые ФИЗИЧЕСКИ смежны, поэтому я пытаюсь выяснить, почему физическая смежность так важна. Я провел некоторое исследование и, по нескольким источникам, обнаружил следующие причины:

1) улучшает использование кэша и обеспечивает меньшее время доступа к памяти (GigaQuantum: я не понимаю: как?)

2) вам нужно поиграться с таблицами страниц ядра, чтобы отобразить страницы, которые не являются физически смежными (GigaQuantum: я не понимаю этого: разве каждая страница не отображается отдельно? ?)

3) отображение страниц, которые не являются физически смежными, приводит к большему увеличению TLB (GigaQuantum: я не понимаю: как?)

Согласно комментариям, которые я вставил, я не совсем понимаю эти 3 причины. Ни один из моих исследовательских источников не смог адекватно объяснить / обосновать эти 3 причины. Кто-нибудь может объяснить это немного подробнее?

Спасибо! Поможет мне лучше понять ядро ​​...

Ответы [ 6 ]

6 голосов
/ 16 ноября 2011

Главный ответ действительно заключается в вашем втором пункте.Как правило, когда память выделяется в ядре, она не отображается во время выделения - вместо этого ядро ​​отображает столько физической памяти, сколько оно может заранее, используя простое линейное отображение.Во время выделения он просто выделяет часть этой памяти для выделения - поскольку отображение не изменилось, оно уже должно быть непрерывным.

Эффективно большое линейное отображение физической памяти: оба из-за большогодля него можно использовать страницы (которые занимают меньше места для записей таблицы страниц и меньше записей TLB), а также потому, что изменение таблиц страниц является медленным процессом (поэтому вам следует избегать этого во время выделения / освобождения).

Выделения, которые являются только логически линейными , могут запрашиваться с использованием интерфейса vmalloc() вместо kmalloc().

В 64-битных системах отображение ядра может охватывать все физическоепамять - в 32-разрядных системах (кроме систем с небольшим объемом физической памяти) только часть физической памяти напрямую отображается.

5 голосов
/ 14 ноября 2011

На самом деле поведение распределения памяти, которое вы описываете, является общим для многих ядер ОС, и основная причина - это распределение физических страниц ядра.Как правило, ядро ​​имеет один физический распределитель страниц, который используется для выделения страниц как для пространства ядра (включая страницы для DMA), так и для пространства пользователя.В пространстве ядра вам нужна непрерывная память, потому что дорого (для кода в ядре) отображать страницы каждый раз, когда они вам нужны.Например, на x86_64 это абсолютно бесполезно, потому что ядро ​​может видеть все адресное пространство (в 32-битных системах ограничение 4G виртуального адресного пространства, поэтому обычно верхний 1G выделен для ядра, а нижний 3G для пользовательского пространства).

Ядро Linux использует buddy алгоритм для выделения страниц, так что выделение большего фрагмента занимает меньше итераций, чем выделение меньшего фрагмента (ну, меньшие фрагменты получаются путем разделения больших фрагментов).Более того, использование одного распределителя как для пространства ядра, так и для пространства пользователя позволяет ядру уменьшить фрагментацию.Представьте, что вы выделяете страницы для пользовательского пространства на 1 страницу за итерацию.Если пользовательскому пространству нужно N страниц, вы делаете N итераций.Что произойдет, если ядру понадобится непрерывная память?Как он может создать достаточно большой непрерывный блок, если вы украли 1 страницу из каждого большого блока и передали их в пространство пользователя?

[update]

На самом деле ядро ​​выделяет континуумыблоки памяти для пользовательского пространства не так часто, как вы думаете.Конечно, он выделяет их при создании ELF-образа файла, когда он создает заголовок для чтения, когда пользовательский процесс читает файл, он создает их для операций IPC (конвейер, буферы сокетов) или когда пользователь передает флаг MAP_POPULATE в системный вызов mmap.Но обычно ядро ​​использует «ленивую» схему загрузки страниц.Он предоставляет непрерывное пространство виртуальной памяти для пространства пользователя (когда пользователь делает malloc первый раз или делает mmap), но не заполняет пространство физическими страницами.Он распределяет страницы только тогда, когда происходит сбой страницы.То же самое верно, когда пользовательский процесс делает fork.В этом случае дочерний процесс будет иметь адресное пространство «только для чтения».Когда потомок изменяет некоторые данные, происходит сбой страницы, и ядро ​​заменяет страницу в дочернем адресном пространстве новой (так что у родителя и потомка теперь разные страницы).Обычно в этих случаях ядро ​​выделяет только одну страницу.

Конечно, существует большой вопрос фрагментации памяти.Пространство ядра всегда нуждается в непрерывной памяти.Если бы ядро ​​выделяло страницы для пользовательского пространства из «случайных» физических мест, было бы гораздо сложнее получить большой кусок непрерывной памяти в ядре через некоторое время (например, после недели работы системы).В этом случае память будет слишком фрагментированной.

Для решения этой проблемы ядро ​​использует схему readahead.Когда сбой страницы происходит в адресном пространстве какого-либо процесса, ядро ​​выделяет и отображает более одной страницы (поскольку существует вероятность, что процесс будет считывать / записывать данные со следующей страницы).И, конечно, в этом случае он использует физически непрерывный блок памяти (если это возможно).Просто чтобы уменьшить потенциальную фрагментацию.

2 голосов
/ 15 ноября 2011

Пару, о чем я могу думать:

  • Аппаратное обеспечение DMA часто обращается к памяти с точки зрения физических адресов. Если у вас есть несколько страниц данных для передачи с аппаратного обеспечения, вам понадобится непрерывный кусок физической памяти для этого. Некоторые старые контроллеры DMA даже требуют, чтобы память была расположена по низким физическим адресам.
  • Позволяет ОС использовать большие страницы. Некоторые блоки управления памятью позволяют использовать больший размер страницы в записях таблицы страниц. Это позволяет вам использовать меньше записей таблицы страниц (и слотов TLB) для доступа к тому же количеству виртуальной памяти. Это уменьшает вероятность пропуска TLB. Конечно, если вы хотите выделить страницу размером 4 МБ, вам потребуется 4 МБ непрерывной физической памяти для ее поддержки.
  • Ввод-вывод с отображением в память. Некоторые устройства могут быть сопоставлены с диапазонами ввода / вывода, для которых требуется непрерывный диапазон памяти, охватывающий несколько кадров.
1 голос
/ 31 июля 2013

Запрос на выделение непрерывной или несмежной памяти от ядра зависит от вашего приложения.

Например, выделение непрерывной памяти: если вам требуется выполнить операцию DMA, то вы будете запрашивать непрерывную память через kmallocДля вызова () в качестве операции DMA требуется память, которая также является физически смежной, поскольку в DMA вы будете указывать только начальный адрес блока памяти, а другое устройство будет выполнять чтение или запись из этого расположения.

Некоторые изОперация не требует непрерывной памяти, поэтому вы можете запросить кусок памяти через vmalloc (), который дает указатель на незаразную физическую память.

Таким образом, он полностью зависит от приложения, запрашивающего память.

Пожалуйста, помните, что хорошей практикой является то, что если вы запрашиваете смежную память, то она должна основываться только на том, что ядро ​​пытается наилучшим образом выделить память, которая является физически смежной. Ну что же, kmalloc () и vmalloc ()также имеет свои пределы.

0 голосов
/ 25 февраля 2017
Ядро

не нуждается в физически смежных страницах, на самом деле оно просто нуждается в эффективности и стабильности.монолитное ядро ​​имеет тенденцию иметь одну таблицу страниц для пространства ядра, разделяемого между процессами, и не хочет ошибок страниц в пространстве ядра, что делает конструкции ядра слишком сложными

, поэтому обычные реализации в 32-битной архитектуре всегда разделяются на 3g / 1g для 4gадресное пространство для пространства ядра 1g, нормальные отображения кода и данных не должны генерировать рекурсивные ошибки страниц, которые слишком сложны для управления: вам нужно найти пустые фреймы страниц, создать отображение в mmu и обработать сброс tlb для новых отображений на каждой стороне ядраЯдро сбоев страниц уже занято выполнением сбоев страниц на стороне пользователя

Более того, линейное отображение 1: 1 может иметь гораздо меньше записей в таблице страниц, поскольку оно может использовать больший размер страницы (> 4 КБ), меньше записей приводит к меньшему количеству записей.tlb пропускает.

, поэтому распределитель собеседников в линейном адресном пространстве ядра всегда обеспечивает физически непрерывные фреймы страниц, даже большинству кодов не нужны непрерывные фреймы, но многие драйверы устройств, которым требуются непрерывные фреймы страниц, уже считают, чтовыделенные буферы через общий распределитель ядра физически непрерывны

0 голосов
/ 14 ноября 2011
  1. Помещение объектов, которые мы будем много читать, физически близко друг к другу, использует пространственную локальность, вещи, которые нам нужны, с большей вероятностью будут кэшироваться.

  2. Не уверен насчет этого

  3. Я считаю, что это означает, что если страницы не являются смежными, TLB должен сделать больше работы, чтобы выяснить, где они все находятся.Если они допустимы, мы можем выразить все страницы процесса как PAGES_START + PAGE_OFFSET.Если это не так, нам нужно хранить отдельный индекс для всех страниц данного процесса.Поскольку TLB имеет конечный размер, и нам нужно получить доступ к большему количеству данных, это означает, что мы будем гораздо больше менять местами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...