создание собственной функции malloc?

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

спасибо

6 ответов


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

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

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

конечно, если вы запросили больше, он вернул NULL.

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

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


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


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

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

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


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


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

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

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

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

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

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

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

посмотреть пулов памяти и obstacks.