Спеціальні розподільники купи


9

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

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

Програмування ігор (принаймні, з тими іграми, які амбіційно налаштовані на апаратне забезпечення) іноді потрапляє між ними: ви можете використовувати динамічне розподілення, але є достатньо пам'яті та м'яких обмежень у реальному часі, що ви не можете ставитися до розподільника як до чорного поля , не кажучи вже про використання сміття, тож вам доведеться використовувати спеціальні розподільники. Це одна з причин, що C ++ все ще широко використовується в ігровій індустрії; це дозволяє робити такі речі, як http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2271.html

Які ще домени знаходяться на території між ними? Де, крім ігор, широко використовуються спеціальні розподільники?


1
Деякі ОС використовують плоский розподільник, який забезпечує кешування об'єктів, але також може бути використаний для зменшення конфліктів пропусків кешу процесора шляхом зіставлення членів об'єкта в різні набори для індексованого кешу модуля 2 ** N (обидва, маючи кілька примірників у суміжній пам'яті та за допомогою змінної прокладки всередині плити). Поведінка кеша може бути важливішим, ніж швидкість розподілу / вільної швидкості або використання пам'яті в деяких випадках.
Пол А. Клейтон

Відповіді:


4

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

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

Щоб навести декілька прикладів ... в першій своїй компанії я працював над пакетом Historian, програмним забезпеченням, відповідальним за збір / зберігання / архівування даних управління процесами (подумайте про завод, атомну електростанцію чи нафтопереробний завод з 10-мільйонними датчиками, ми збережемо ці дані). Щоразу, коли ми аналізували будь-яке вузьке місце, яке заважало Historian обробляти більше даних, більшість часу проблема полягала в тому, як оброблялася пам'ять. Ми пройшли велику відстань, щоб переконатися, що malloc / free не називались, якщо вони абсолютно не потрібні.

На своїй нинішній роботі я працюю над цифровим рекордером відеоспостереження та пакетом аналізу. При 30 кадрів в секунду кожен канал отримує відео кадр кожні 33 мілісекунди. На обладнання, яке ми продаємо, ми можемо легко записати 100 каналів відео. Отже, це ще один випадок, щоб переконатися, що на критичному шляху (мережевий виклик => захоплення компонентів => програмне забезпечення для управління записом => компоненти зберігання => диск) немає динамічного розподілу пам'яті. У нас є спеціальний алокатор кадру, який містить відряди буферів фіксованого розміру і використовує LIFO для повторного використання раніше виділених буферів. Якщо вам потрібно 600 Кб пам’яті, можливо, ви отримаєте буфер 1024 Кб, який витрачає простір, але оскільки він підібраний спеціально для нашого використання, коли кожен розподіл дуже короткочасний, він спрацьовує дуже добре, оскільки буфер використовується,

У типі описаних мною програм (переміщення безлічі даних від А до Б та обробка великої кількості запитів клієнтів) перехід до купи та назад є основним джерелом вузьких місць роботи процесора. Зведення фрагментації купи до мінімуму є вторинною перевагою, однак, наскільки я можу сказати, більшість сучасних ОС вже реалізують купи з низькою фрагментацією (як мінімум, я знаю, що це робить Windows, і я би сподівався, що і інші). Особисто за 12+ років, працюючи в таких типах середовищ, я часто бачив проблеми використання процесора, пов’язані з купою, хоча жодного разу не бачив системи, яка насправді страждала від роздробленої купи.


"Ми пройшли велику відстань, щоб переконатися, що malloc / free не викликали, якщо вони абсолютно не потрібні ..." - Я знаю деяких апаратників, які створюють маршрутизатори. Вони навіть не турбуються malloc/free. Вони резервують блок пам'яті та використовують його як структуру даних курсору. Більша частина їх роботи зводилася до відстеження показників.

4

Обробка відео, VFX, операційні системи тощо. Хоча люди часто надмірно ними користуються. Структура даних та розподільник не потребують розділення для ефективного розподілу.

Наприклад, це вводить багато зайвих складностей для розділення ефективного розподілу вузлів дерев в octree подалі від самого octree та покладання на зовнішній розподільник. Це не обов'язково порушення SRP, щоб зв'язати ці дві проблеми разом і покласти на себе обов'язок октрису одночасно виділяти багато вузлів, оскільки це не збільшує кількість причин для зміни. Це, практично кажучи, може зменшити його.

Наприклад, у C ++, один із затримкових побічних ефектів того, що стандартні контейнери покладаються на зовнішній розподільник, зробив пов'язані структури, такі як std::mapіstd::list вважаються майже непотрібними спільнотою C ++, оскільки вони орієнтують їх наstd::allocatorпри цьому ці структури даних виділяють по одному вузлу. Звичайно, ваші зв'язані структури в цьому випадку будуть погано працювати, але все вийшло б настільки інакше, якби ефективне розподіл вузлів для зв'язаних структур вважалося відповідальністю структури даних, а не розподільником. Вони все ще можуть використовувати призначене для користувача виділення з інших причин, наприклад, відстеження / профілювання пам'яті, але покладатися на розподільник, щоб зробити пов'язані структури ефективними, намагаючись виділити вузли одночасно, робить їх усі за замовчуванням надзвичайно неефективними, що було б добре, якби це було з відомим застереженням, що для пов'язаних структур тепер потрібен спеціальний розподільник, як-от безкоштовний список, щоб бути достатньо ефективним та уникати запуску пропусків кешу зліва та справа. Набагато практичніше може бути щось подібнеstd::list<T, BlockSize, Alloc>, де BlockSizeвказується кількість суміжних вузлів, які потрібно виділити одразу для вільного списку (зазначення 1 фактично призведе до того, std::listяк є зараз).

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


3

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

Де, крім ігор, широко використовуються спеціальні розподільники?

Facebook

Перевірте jemalloc, який Facebook починає використовувати для поліпшення їхньої роботи та зменшення фрагментації.


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