сделать свою собственную функцию malloc? - PullRequest
10 голосов
/ 16 января 2011

Я читал, что некоторые игры переписывают свои собственные malloc для большей эффективности. Я не понимаю, как это возможно в мире виртуальной памяти. Если я правильно помню, malloc фактически вызывает специфическую для ОС функцию, которая отображает виртуальный адрес в реальный адрес с помощью MMU. Итак, как же кто-то может сделать свой собственный распределитель памяти и распределить реальную память, не вызывая malloc фактической среды выполнения?

Спасибо

Ответы [ 6 ]

8 голосов
/ 16 января 2011

Конечно, можно написать распределитель, более эффективный, чем универсальный.

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

Пример: много лет назад нам пришлось разрабатывать и кодировать коммуникационную подсистему (HDLC, X.25 и проприетарные уровни) для встроенных систем.Тот факт, что мы знали, что максимальное выделение всегда будет меньше 128 байт (или что-то в этом роде), означало, что нам вообще не пришлось возиться с блоками переменного размера. Каждое выделение было для 128 байт независимо от того, сколько вы запрашивали.

Конечно, если вы запрашивали больше, он возвращает NULL.

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

Конечно, это был особый случай, но вы также обнаружите, что это относится и к играм.Фактически, мы даже использовали это в системе общего назначения, где выделения ниже определенного порогового значения получали фиксированный объем памяти из предварительно выделенного пула с самоуправлением, выполняемого таким же образом.Любые другие распределения (превышающие пороговое значение или если пул был полностью распределен) были отправлены в «реальный» malloc.

3 голосов
/ 16 января 2011

В общем случае malloc будет вызывать специфическую для ОС функцию, чтобы получить кучу памяти (по крайней мере, одну страницу виртуальной машины), а затем разделить эту память на более мелкие порции, если это необходимо для возврата к вызывающему malloc. *

Библиотека malloc также будет иметь список (или списки) свободных блоков, поэтому она часто может удовлетворить запрос, не запрашивая у ОС дополнительной памяти. Определение количества блоков разных размеров для обработки, решение о том, пытаться ли объединить смежные свободные блоки и т. Д., - это выбор, который должен сделать разработчик библиотеки malloc.

Вы можете обойти библиотеку malloc и напрямую вызвать на уровне ОС функцию «дай мне немного памяти» и выполнить собственное выделение / освобождение в памяти, которую вы получаете от ОС. Такие реализации, вероятно, будут зависеть от ОС. Другой альтернативой является использование malloc для начальных выделений, но ведение собственного кеша освобожденных объектов.

3 голосов
/ 16 января 2011

То, что malloc() является стандартной функцией C, не означает, что это самый низкий уровень доступа к системе памяти. Фактически, malloc(), вероятно, реализован с точки зрения функциональности операционной системы более низкого уровня. Это означает, что вы также можете вызывать эти интерфейсы более низкого уровня. Они могут зависеть от ОС, но они могут позволить вам более высокую производительность, чем вы получаете от интерфейса malloc(). Если бы это было так, вы могли бы реализовать свою собственную систему выделения памяти любым удобным для вас способом, и, возможно, быть еще более эффективной в этом - например, оптимизировать алгоритм под характеристики размера и частоты выделений, которые вы собираетесь выполнять .

2 голосов
/ 16 января 2011

Если я правильно помню, malloc фактически вызывает специфическую для ОС функцию

Не совсем.Большая часть оборудования имеет размер страницы 4 КБ.Операционные системы, как правило, не предоставляют интерфейс выделения памяти, предлагающий что-то меньшее, чем куски размера страницы (и выровненные по страницам).

malloc тратит большую часть своего времени на управление уже выделенным пространством виртуальной памятии только иногда запрашивает больше памяти у ОС (очевидно, это зависит от размера элементов, которые вы выделяете, и от того, как часто вы free).

Существует распространенное заблуждение, что когда вы free что-тонемедленно возвращается в операционную систему.Хотя это иногда происходит (особенно для больших блоков памяти), обычно free d памяти остается выделенным для процесса и может быть повторно использовано более поздними malloc с.

Так что большинстворабота ведется в бухгалтерии уже выделенного виртуального пространства.Стратегии распределения могут иметь много целей, таких как быстрая работа, низкая потеря памяти, хорошая локальность, пространство для динамического роста (например, realloc) и т. Д.

Если вы знаете больше о своей структуре распределения памяти ивыпуская, вы можете оптимизировать malloc и free для своих шаблонов использования или предоставить более расширенный интерфейс.

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

Посмотрите на пулы памяти и obstacks .

2 голосов
/ 16 января 2011

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

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