Вы правы, это обычная проблема. [Редактировать: как сделать выделение по фиксированному размеру, я имею в виду. «malloc
замедляет мое приложение», реже, чем вы думаете.
Если ваш код слишком медленный и malloc
правдоподобный преступник, то простой распределитель ячеек (или пул памяти) может улучшить ситуацию. Вы почти наверняка можете найти где-нибудь, или легко написать:
Выделите большой блок и поместите узел с одиночной связью в начале каждой ячейки из 16 байтов. Свяжите их все вместе.Чтобы выделить, выньте голову из списка и верните его. Чтобы освободить, добавьте ячейку в начало списка. Конечно, если вы попытаетесь выделить и список пуст, вам нужно выделить новый большой блок, разделить его на ячейки и добавить их в список.
Вы можете избежать этой большой работы, если хотите. Когда вы выделяете большой блок, просто сохраните указатель на его конец. Чтобы выделить, переместите указатель назад на 16 байтов через блок и верните новое значение. Если это уже не было в начале блока [*], конечно. Если это произойдет, и свободный список также пуст, вам нужен новый большой блок. Бесплатно не меняется - просто добавьте узел в свободный список.
У вас есть выбор, нужно ли сначала вывести из блока и проверить свободный список, если он исчерпан, или сначала проверить бесплатный список, и отменить блок, если он пуст. Я не знаю, что имеет тенденцию быть более быстрым - хорошая вещь о свободном списке «последний в первом» - это то, что он не похож на кеш, поскольку вы используете память, которая использовалась недавно, поэтому я, вероятно, первый.
Обратите внимание, что узел списка не нужен, пока ячейка выделена, поэтому на ячейку по существу нулевые служебные данные. Вряд ли в стороне от скорости, это, вероятно, будет преимуществом по сравнению с malloc
или другими распределителями общего назначения.
Помните, что удаление всего распределителя - это единственный способ вернуть память обратно в систему, поэтому пользователи, которые планируют выделять много ячеек, использовать их и освобождать их, должны создавать свои собственные распределитель, использовать его, а затем уничтожить. Как для производительности (вам не нужно освобождать все ячейки), так и для предотвращения эффекта фрагментарного стиля, когда весь блок должен храниться, если какая-либо из его ячеек используется. Если вы не можете этого сделать, использование вашей памяти будет ярким знаком времени, в течение которого ваша программа была запущена. Для некоторых программ это проблема (например, долговременная программа со случайными большими всплесками в памяти, в системе, где ограничена память). Для других это абсолютно нормально (например, если количество используемых ячеек увеличивается до самого конца программы или колеблется в пределах диапазона, где вам действительно все равно, что вы используете больше памяти, чем вы могли). Для некоторых это очень желательно (если вы знаете, сколько памяти вы собираетесь использовать, вы можете выделить все это и не беспокоиться о сбоях). В этом отношении некоторые реализации malloc
затрудняют выпуск памяти из процесса в ОС.
[*] Где «начало блока», вероятно, означает «начало блока, а также размер какого-либо узла, который используется для поддержки списка всех блоков, поэтому они могут быть освобождены, когда распределитель ячеек разрушен».
ли вам эта память «один выстрел», как, скажем, для некоторого алгоритма или будете делать это по ходу (что может быть очень долго?) – Skurmedel
Одним из критериев при разработке библиотеки распределения является то, насколько хорошо он будет работать при таких обстоятельствах и под еще более недружелюбными. В то время как реализация пользовательских процедур распределения является хорошей забавой, вам, вероятно, это не нужно. –
@Skurmedel - будет запрошено и выпущено множество небольших бит памяти во время выполнения программы. – mmmmalloc