Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности

Новые сообщения [новые:0]
Дайджест
Горячие темы
Избранное [новые:0]
Форумы
Пользователи
Статистика
Статистика нагрузки
Мод. лог
Поиск
|
|
03.04.2014, 18:27
|
|||
|---|---|---|---|
Фрагментация памяти. Аллокаторы. |
|||
|
#18+
Предположим, есть некое нагромождение разных контейнеров, реализующих NoSQL-БД в памяти. Все эти контейнеры используют std::allocator. Занимает это всё в рабочем режиме, допустим, 100 гигов. Есть другая часть программы, отвечающая за пост-обработку данных в ходе каждого запроса, приём соединений, отвечаниями на запросы. Например, выдернуть из основного хранилища 128 каких-нибудь элементов, хитро отсортировать, найти для первых 20 ещё что-нибудь и засунуть в сокет в виде своего бинарного протокола... Эта "другая часть" тоже оперирует разными контейнерами, стандартными и нестандартными, но все они юзают std::allocator, хотя конечно сами и создаются на стеке. Как сильно я облегчу потребление памяти процессом в результате дефрагментации, если "сниму нагрузку" с std::allocator из "другой части"? Скажем, создам аллокатор типа POOL, который всегда держит выделенными 100 мегабайт, отдаёт потребителям кусочки с начала, а после обработки запроса сдвигает указатель на начало? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
03.04.2014, 18:34
|
|||
|---|---|---|---|
Фрагментация памяти. Аллокаторы. |
|||
|
#18+
боевыеКак сильно я облегчу потребление памяти процессом в результате дефрагментации, если "сниму нагрузку" с std::allocator из "другой части"? Скажем, создам аллокатор типа POOL, который всегда держит выделенными 100 мегабайт, отдаёт потребителям кусочки с начала, а после обработки запроса сдвигает указатель на начало? Однозначно увеличится производительность проги, если вместо системного вызова malloc через ::new, через std::allocator::allocate на каждый чих будет просто возвращение готового указателя из пула. 100 MB в окупации- это вообще ни о чём, для современных машин. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
03.04.2014, 18:55
|
|||
|---|---|---|---|
Фрагментация памяти. Аллокаторы. |
|||
|
#18+
А что вы думаете делает стандартный аллокатор? Сегодня 2014 год. Чаще всего когда вы пытаетесь вмешаться в его работу, происходит замедление. Пул поможет лишь в двух случаях: 1. Выделяются много _равных по размеру_ участков памяти (хотя этот случай современными аллокаторами тоже отрабатывает хорошо, системного вызова скорее не произойдет, как и блокировки). 2. Выделяются много мелких _связанных_ объектов, которые затем освобождаются единовременно. Также, очень сложно реализовать хороший эффективный пул, нужно будет решать кучу проблем: выравнивание, недостаточный размер, в С++ в добавок к этому - явный вызов деструкторов. Поэтому надо все взвесить перед тем как делать свои аллокаторы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
03.04.2014, 19:12
|
|||
|---|---|---|---|
Фрагментация памяти. Аллокаторы. |
|||
|
#18+
На самом деле пул-аллокатор свой сделан и я делаю эксперименты, смотрю на графики потребления памяти. Идея была в том, чтобы снять нагрузку с std::allocator, чтобы все "new" случившиеся в ходе обработки одного запроса заменились на тупой сдвиг указателя, а по окончании запроса двигать указатель на начало пула. Графики говорят, что особенного выигрыша нет. С std::allocator график более рваный, но в конечном итоге он дрыгается вокруг стабильного значения и утечек от фрагментации особо страшных я не вижу. С моим аллокатором график более ровный, но других особых преймуществ, кроме ровности графика, я не вижу, может быть скорость работы программы, но это не мерялось. Конечно new - это не вызов в ядро и даже не библиотечный malloc каждый раз, а всего-лишь ключевое слово языка, на которое компилятор рожает вызов конструктора, но как он выделит под объект память в куче - не факт, что это всегда будет дороже, чем мой сдвиг указателя. Короче говоря, дело тёмное, нужен НИОКР. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
03.04.2014, 19:14
|
|||
|---|---|---|---|
Фрагментация памяти. Аллокаторы. |
|||
|
#18+
sherzod_ 1. Выделяются много _равных по размеру_ участков памяти (хотя этот случай современными аллокаторами тоже отрабатывает хорошо, системного вызова скорее не произойдет, как и блокировки). Вызовы происходят, просто сделайте свой аллокатор, пропишите в allocate, construct, deallocate, destroy выводы отчётов с std::cout передайте аллокатор в контейнеры, делайте insert, erase, reserve, push и пр. и смотрите на вывод в консоль. Узнаете много интересного про политики управления памятью, реализованные в контейнерах. ЗЫ std::allocator не делет в плане оптимизации управления памятью ничего, он просто делает new, delete. Политика управления памятью есть в контейнерах, она своя для каждого, и, судя по выводам std::cout, очень не оптимальна, заточена под общий случай. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
03.04.2014, 19:20
|
|||
|---|---|---|---|
Фрагментация памяти. Аллокаторы. |
|||
|
#18+
боевыеКонечно new - это не вызов в ядро и даже не библиотечный malloc каждый раз, а всего-лишь ключевое слово языка, на которое компилятор рожает вызов конструктора, но как он выделит под объект память в куче - не факт, что это всегда будет дороже, чем мой сдвиг указателя. Удивил new это вообще выделение в динамической памяти, куда пихается структура класса. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
03.04.2014, 19:24
|
|||
|---|---|---|---|
Фрагментация памяти. Аллокаторы. |
|||
|
#18+
smaldsherzod_1. Выделяются много _равных по размеру_ участков памяти (хотя этот случай современными аллокаторами тоже отрабатывает хорошо, системного вызова скорее не произойдет, как и блокировки). Вызовы происходят, просто сделайте свой аллокатор, пропишите в allocate, construct, deallocate, destroy выводы отчётов с std::cout передайте аллокатор в контейнеры, делайте insert, erase, reserve, push и пр. и смотрите на вывод в консоль. Узнаете много интересного про политики управления памятью, реализованные в контейнерах. ЗЫ std::allocator не делет в плане оптимизации управления памятью ничего, он просто делает new, delete. Политика управления памятью есть в контейнерах, она своя для каждого, и, судя по выводам std::cout, очень не оптимальна, заточена под общий случай. Я так игрался когда-то. Эта политика примерно понятна, ясно в целом как себя ведут разные контейнеры, не в этом дело. Дело в том, что даже обычный new может быть не так дорог как мне кажется. Это может на практике обернуться тоже каким-нибудь тупым сдвигом указателя... Ну например, во freebsd, насколько я слышал, есть (помимо тупой кучи) пулы с кусочками по 8, 16, 32, 64, 128... байт памяти, одна из защит от фрагментации. Сколько там таких чудес я точно не знаю ) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
03.04.2014, 19:45
|
|||
|---|---|---|---|
|
|||
Фрагментация памяти. Аллокаторы. |
|||
|
#18+
боевые, Я бы подошел с другой стороны. Сделал бы для базы данных кастомный аллокатор на основе huge pages а для мелочи оставил бы тот что есть ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
03.04.2014, 19:51
|
|||
|---|---|---|---|
Фрагментация памяти. Аллокаторы. |
|||
|
#18+
smaldsherzod_1. Выделяются много _равных по размеру_ участков памяти (хотя этот случай современными аллокаторами тоже отрабатывает хорошо, системного вызова скорее не произойдет, как и блокировки). Вызовы происходят, просто сделайте свой аллокатор, пропишите в allocate, construct, deallocate, destroy выводы отчётов с std::cout передайте аллокатор в контейнеры, делайте insert, erase, reserve, push и пр. и смотрите на вывод в консоль. Узнаете много интересного про политики управления памятью, реализованные в контейнерах. ЗЫ std::allocator не делет в плане оптимизации управления памятью ничего, он просто делает new, delete. Политика управления памятью есть в контейнерах, она своя для каждого, и, судя по выводам std::cout, очень не оптимальна, заточена под общий случай. Вы или троллите, или если нет - то у вас все смешалось в кучу. Тут говорится не о внутренней кухне контейнеров, а о внутренностях malloc - погуглите словосочетание "системный вызов". ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
03.04.2014, 20:00
|
|||
|---|---|---|---|
Фрагментация памяти. Аллокаторы. |
|||
|
#18+
Проблема в том, что для хранения данных используется контейнер btree - это дерево такое, которое иногда при вставке новых данных проводит операции убиения старых нодов, чтобы заместить их нодами увеличенного размера ( 64 -> 128 -> 256 -> 512 ). Нужен аллокатор, который помнит размеры выделенных кусков, иначе потери от хранения ненужных данных в POOL-аллокаторе превысят размер памяти, используемой для хранения служебной информации в std::allocator. С чем-то типа std::map, который при вставке не занимается никакими удалениями этот фокус прокатывает лучше. Меня тут посетила мысль. Когда наступают такие условия в b-tree, при которых ему захотелось увеличить некий узел в 2 раза, то он выделяет 2*N байт памяти, а освобождает N байт (я смотрел код гуглового, который у меня используется). Получается, что у кучи попросили 2*N байт, а освободили N. То есть, при постоянной вставке объектов, btree-контейнер периодически бросает мелкие куски, а просит куски больше старых - то есть делает такие запросы в кучу, которые не могут быть удовлетворены за счёт выдачи клиенту освобождённых им в прошлом блоков. Никому больше эта дырка в куче размером в N байт не нужна. Хотя btree ведь выделяет когда-то и блоки по N байт, если это совсем новый узел. Или стандартный алгоритм выделения памяти не сканирует кучу на предмет поиска мелких дырок подходящего размера? Разве у него нет списка дырок в каком-нибудь быстром индексе, чтобы быстро их находить? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
03.04.2014, 22:13
|
|||
|---|---|---|---|
Фрагментация памяти. Аллокаторы. |
|||
|
#18+
боевыечтобы заместить их нодами увеличенного размера в B и B* деревьях при переполнеии делается расщепление узла ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
03.04.2014, 22:32
|
|||
|---|---|---|---|
Фрагментация памяти. Аллокаторы. |
|||
|
#18+
sherzod_ Как работает malloc знаю по исходникам libc и ядер линукса и опен соляриса. Выше говорилось именно про внутреннюю кухню аллокаторов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
03.04.2014, 22:34
|
|||
|---|---|---|---|
Фрагментация памяти. Аллокаторы. |
|||
|
#18+
боевыеfreebsd В линуксах есть slab. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
03.04.2014, 22:39
|
|||
|---|---|---|---|
Фрагментация памяти. Аллокаторы. |
|||
|
#18+
боевые Или стандартный алгоритм выделения памяти не сканирует кучу на предмет поиска мелких дырок подходящего размера? Разве у него нет списка дырок в каком-нибудь быстром индексе, чтобы быстро их находить? Какая у Вас ОC? Просто в линукс ядрах как раз эти задачи решает slab аллокатор. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
04.04.2014, 00:16
|
|||
|---|---|---|---|
|
|||
Фрагментация памяти. Аллокаторы. |
|||
|
#18+
smaldКакая у Вас ОC? Просто в линукс ядрах как раз эти задачи решает slab аллокатор. А причем здесь ядро к выделению памяти в процессе? Ядерным slab процесс никак не может воспользоваться. У ядра по любому запрашиваются куски с кратностью в страницу (через mmap или аналогичный механизм). Из них формируются кучи. А разные схемы аллокации реализуются уже над кучами на уровне libc и выше. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
04.04.2014, 00:54
|
|||
|---|---|---|---|
Фрагментация памяти. Аллокаторы. |
|||
|
#18+
Anatoly MoskovskyА причем здесь ядро к выделению памяти в процессе? Ядерным slab процесс никак не может воспользоваться. У ядра по любому запрашиваются куски с кратностью в страницу (через mmap или аналогичный механизм). Из них формируются кучи. Ну например, во freebsd, насколько я слышал, есть (помимо тупой кучи) пулы с кусочками по 8, 16, 32, 64, 128... байт памяти, одна из защит от фрагментации. Вы упомянули про менеджеры памяти в ядре freebsd, подумал, что затронули тему распределителей памяти в ядре, и связали степень совершенства их алгоритмов с возможностью использовать std::allocator, без опасения в появлении фрагментированности кучи, от прямого выполнения в нём malloc и free для массивов разных размеров. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|

start [/forum/topic.php?fid=57&mobile=1&tid=2019568]: |
0ms |
get settings: |
9ms |
get forum list: |
12ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
53ms |
get topic data: |
14ms |
get forum data: |
3ms |
get page messages: |
55ms |
get tp. blocked users: |
1ms |
| others: | 15ms |
| total: | 170ms |

| 0 / 0 |
