Чи може хтось пояснити цю діаграму про розподіл плит?


10

Я намагаюся зрозуміти, як працює розподіл Slab і чому він відрізняється чи кращий, ніж звичайний пейджинг.

Я знайшов цю діаграму, яка, на мою думку, була б корисною, якби вона мала більше пояснень.

Деякі питання:

  • Що представляють елементи 3KB та 7KB? Повинні вони якось пов’язані? Чому вони упаковані саме так?
  • У стовпці "Кеші" є кеші сірими полями, або біло / блакитними полями всередині сірих полів? Чи є сірі скриньки пакетом схованок?
  • Це лише плити - блакитні коробки або цілі сторінки "Фізичні суміжні сторінки"?

Я дуже вдячний за допомогу. Дякую!

Виділення плит

Відповіді:


15

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

Спочатку давайте подумаємо, чому ядро ​​потребує розподільника пам'яті нижче рівня сторінок. Це, мабуть, уже речі, які ви здебільшого знаєте, але я перегляну його для повноти.

Сторінки - це типова «одиниця» операцій із пам’яттю. Коли програма для користувальницького простору виділяє пам'ять, або пам'ять-карту, або щось подібне, воно зазвичай отримує кратне розмір машинної сторінки. Є помітні деякі винятки; Windows використовує 64k як одиницю розподілу віртуальної пам'яті незалежно від розміру сторінки процесора. Тим не менш, давайте подумаємо про це так.

У сучасному процесорі, що стосується коду простору користувача, він має рівний адресний простір. Це насправді ілюзія, яку надає система віртуальної пам'яті. ОС надає сторінки з будь-якої точки оперативної пам’яті (або, можливо, зовсім не в оперативній пам’яті, у випадку розміщеної пам’яті або файлів, зіставлених з пам’яттю), і відображає їх у суміжний віртуальний адресний простір.

Сенс всього цього полягає в тому, що, крім кількох спеціальних випадків для самої операційної системи (можливо, буфери DMA, можливо, деякі спеціальні структури даних, встановлені під час завантаження, о, і саме зображення ядра), ядро ​​операційної системи, ймовірно, ніколи не повинно керувати будь-яким блоком оперативної пам’яті, більшим за сторінку. Це надзвичайно спрощує речі, оскільки це означає, що на сторінках кожен розподіл і розміщення розмірів мають однаковий розмір. Це також ефективно усуває зовнішню фрагментацію на макрорівні.

Однак ядрам також потрібно реалізувати деякі власні структури даних, і для цього їм потрібен інший вид розподільника пам'яті. Ці структури даних зазвичай можна розглядати як сукупність окремих об'єктів (наприклад, об'єктом може бути "нитка" або "мутекс"). Розмір цих об'єктів, як правило, набагато менший за розмір сторінки.

Так, наприклад, об'єкт, який представляє облікові дані процесу (подумайте про ідентифікатор користувача та ідентифікатор групи в POSIX, скажімо), може становити лише 16 байт або близько того, тоді як "процес" або "потік" може бути до Розміром 1кб. Зрозуміло, що ви не хочете використовувати цілу сторінку для цих невеликих записів, тому ідея полягає у впровадженні алокатора вгорі сторінок.

Система розподілу нижчого рівня повинна задовольняти багато тих же питань, що й розподільник рівня сторінки: вона повинна бути досить швидкою (у тому числі для багатоядерних систем), ви хочете мінімізувати фрагментацію тощо. Але що ще важливіше, воно повинно бути налаштоване та налаштоване залежно від того, яку структуру даних ви зберігаєте.

Деякі структури даних по суті є "схожими на кеш". Наприклад, багато операційних систем підтримують кеш імен шляхів до об’єктів файлової системи, щоб уникнути довгих ланцюгів пошуку каталогу (в Unix-говоріть "кеш імен" або "кеш імені"). Ці об'єкти потрібні лише для продуктивності, а не для коректності, тому ви можете (теоретично) просто забути цілу сторінку, заповнену записами, якщо пам'ять обмежена і вам потрібно швидко звільнити кадр сторінки.

Інші структури даних можуть бути замінені на диск, якщо пам'ять є тісною і вам вона скоро не потрібна. Але ви не хочете цього робити зі структурами даних, які керують свопом, або системою віртуальної пам'яті!

Деякі структури даних можна переміщувати в пам'яті без штрафних санкцій (наприклад, якщо ніхто не звертається до них за допомогою вказівника), тому можна "компактні", щоб уникнути фрагментації, якщо це потрібно.

Отже, основна ідея розподільника плит полягає в тому, що сторінка повинна зберігати лише структури даних одного "типу". Це відмічає всі поля: кожен об’єкт на сторінці має однаковий розмір, тому зовнішньої фрагментації немає. Об'єкти одного "типу" мають однакові вимоги до продуктивності та однакову семантику.

До речі, це подібна історія з виділенням. Для деяких типів об'єктів, ймовірно, добре чекати, якщо немає одразу пам’яті для виділення цього об’єкта. Об'єкт, який представляє відкритий файл, може бути одним із прикладів; відкриття файлу - це дорога операція в найкращі часи, тому чекати трохи більше не зашкодить.

Для інших типів об'єктів (наприклад, об'єкт, який представляє події в реальному часі, які повинні відбутися певний час), ви дійсно не хочете чекати. Тож має сенс для деяких типів об’єктів перерозподілити (скажімо, мати кілька вільних сторінок у запасі), щоб запити можна було задовольнити, не чекаючи.

В основному ви робите це дозволяти кожному типу об'єктів мати власний розподільник, який можна налаштувати для потреб цього об’єкта. Ці алокатори на об'єкти плутано називають "кешами". Ви виділяєте один кеш на тип об'єкта. (Так, ти зазвичай також реалізуєш "кеш кешів".) Кожен кеш зберігає лише об'єкти одного типу (наприклад, лише структури потоків або лише структури простору адрес).

Кожен кеш, у свою чергу, управляє "плитами". Плита - це кадр сторінки, який містить масив об’єктів одного типу. Плити можуть бути "повноцінними" (усі об'єкти, що використовуються), "порожніми" (відсутні об'єкти, які використовуються), або "частковими" (деякі об'єкти, що використовуються).

Часткові плити, мабуть, найцікавіші, оскільки розподільник плит підтримує безкоштовний список для кожної часткової плити. (Повні плити та порожні плити не потребують вільного списку.) Об'єкти виділяються спочатку з часткових плит (і, можливо, спочатку з "найповніших" часткових плит), щоб спробувати уникнути виділення сторінок, які не потрібні.

Приємна річ у розподілі платів полягає в тому, що всі ці параметри політики розподілу (як і семантика пам’яті) можуть бути налаштовані на кожен тип об’єкта. Деякі сховища можуть містити пусту плиту, а деякі - ні. Деякі можуть бути замінені на вторинне сховище, а деякі - ні.

Linux має три різні види розподільника плит, залежно від того, потрібна вам компактність, зручність у кеш-пам'яті чи швидкість роботи в режимі "необмежене". Кілька років тому про це було добре представлено, що добре пояснює компроміси.

Розподільник плит Solaris (детальніше див. У статті ) має ще кілька деталей, щоб досягти ще більшої продуктивності. Для початку в Solaris все робиться з розподілом на плитах, включаючи розподіл кадрів сторінок. (Це рішення Solaris для розподілу об'єктів, розміром яких більше половини сторінки.) Він управляє меншими об'єктами, вкладаючи плити-розподільники у відведений плитою простір.

Деякі об'єкти в Solaris потребують складної та дорогої конструкції та знищення (наприклад, об'єкти, які мають замок ядра), і тому вони можуть бути "частково вільними" (тобто побудованими, але не виділеними). Solaris також оптимізує безкоштовне розподілення платів, підтримуючи безкоштовні списки на основі процесора, гарантуючи, що деякі операції повністю чекають.

Для підтримки розподілу загального призначення (наприклад, для масивів, розмір яких не відомий під час компіляції), більшість операційних систем макрокенера також мають кеші, які представляють розміри об'єктів, а не типи об'єктів . Наприклад, FreeBSD підтримує кеші для невідомих об'єктів, розміри яких мають потужність 2 байти, від 4 до 256.

Я сподіваюся, що ви можете побачити, що розподіл плит - це дуже гнучка рамка, яка може бути налаштована на потреби різних типів даних. Він не конкурує з пейджингом, але доповнює його (хоча в Solaris рамки сторінок виділяються плитами).

Я сподіваюся, що це допомагає. Повідомте мене, якщо щось потребує уточнення.


6

Ідея, що знаходиться під алокатором розподілу даних, полягає в тому, що операційній системі потрібні специфічні, але дещо стандартні структури даних (наприклад, процесорна плата, семафори, метадані файлів тощо), які підказують необхідність використання пам'яті.

Алгоритм розподілення плит забезпечує запаси пам'яті, розміри та ініціалізація яких оптимізовані для цих стандартних структур даних. Наприклад, як видно із зображення, можуть існувати об'єкти об'ємом 3kb, а також об'єкти 7kb. Однак ми знаємо, що ядро ​​виділяє пам'ять лише у кратних розмірах сторінки.

Щоб уникнути втрати часу та пам’яті, ОС зберігається в різних пулах кеш-пам’яті областей пам’яті, які можна швидко розподілити за запитом, а розміри кешу різні для кожного типу об’єктів та структури. Однак кеші безпосередньо не містять і не керують цими областями пам'яті, і навіть не гарантується, що вони перебувають у суміжній пам'яті. Натомість вони розділені на плитах, суміжних сторінках пам'яті, кількість яких зазвичай обирається для зменшення фрагментації пам'яті. Саме в плиті знаходяться різні екземпляри об'єктів, незалежно від того, виділені вони чи вільні. Якщо кеш заповнений, нова плита виділяється десь у первинній пам'яті і додається в кеш.

Підводячи підсумок, речі, які ви можете побачити на малюнку, - це приклади об'єктів, для яких ОС знає, що це 3-7 кВт. Ядро не виділяє пам'ять сторінок спеціально для них, оскільки це би експоненціально збільшило фрагментацію пам'яті, але "перенаправляло" їх до кешу (сіре поле). У кеш-пам’яті повинні бути адреси, які вказують на суміжні ділянки пам’яті, плити (біло / сині набори ящиків) та об’єкти, нарешті, виділяються на ділянці плити (частина, пофарбована синім кольором, серед вільних від повна аналогічна область пам'яті тієї ж плити).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.