Альтернатива C re-alloc / malloc

У меня есть блок памяти, который я хочу перераспределить на другой размер, но меня не волнует, выбрасывается память или нет. Было бы быстрее освободить () память, а затем malloc () новый блок памяти, или это можно сделать с помощью realloc ()?

Я думаю, что оба решения не оптимальны, потому что выполняется дополнительная работа. Я держу пари, что realloc () быстрее находит достаточно большой блок памяти из-за возможности того, что текущий фрагмент будет большим или достаточно маленьким, чтобы вместить новый блок памяти. Но если фрагмент недостаточно велик, он должен скопировать память, чего не делает malloc ().

Я использую Linux. Может быть, для этого есть специальная функция?

Спасибо! :)


person HelloWorld    schedule 10.11.2012    source источник
comment
См. Ответы на этот аналогичный вопрос   -  person Bert    schedule 11.11.2012
comment
Вы также можете взглянуть на stackoverflow.com/questions/13247526: вы - частный случай этого вопроса, где header_size 0.   -  person Steve Jessop    schedule 11.11.2012


Ответы (3)


Если вам не важен контент, стандартная идиома - сделать free, а затем malloc. Найти блок дешевле, чем его скопировать, и нет гарантии, что realloc не выполнит поиск самостоятельно.

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

person user4815162342    schedule 10.11.2012
comment
Единственная причина, по которой я могу думать о том, что realloc будет выигрышем в этом случае, - это тепло кеша (что в современных системах полезно, даже если вы планируете только запись в память). - person Ben Jackson; 11.11.2012
comment
@Ben: и если тепло кеша - это такая огромная проблема на любой данной платформе, можно надеяться, что распределитель памяти вернет последний освобожденный блок, где это возможно. Таким образом, free-then-malloc вернет тот же блок примерно в тех же условиях, что и realloc, хотя, возможно, придется немного подумать, чтобы принять это решение. - person Steve Jessop; 11.11.2012
comment
@SteveJessop Я думал то же самое, но, подумав, я не уверен, разумно ли ожидать, что новое распределение будет просто повторно использовать последний освобожденный блок, если он подходит. По сути, это будет первым подходящим распределением у которого есть свои проблемы. Распределители мощности производства обычно развертывают гибридную стратегию, при которой они могут возвращать первый блок или искать более подходящий, зависимый от множества факторов, таких как размер запроса и фрагментация арены. - person user4815162342; 11.11.2012
comment
@ user4815162342: согласен. Мы пропускаем множество деталей, например, я предполагал, что новый запрос предназначен для большего объема памяти, чем выделенный размер только что освобожденного блока, но меньше, чем базовый размер только что освобожденного блока (т.е. случай, когда вызывающий необходимо перераспределить, но realloc может просто вернуть тот же адрес). Тогда я думаю, что это, вероятно, разумная стратегия для распределителя использовать этот блок. Если бы новый запрос был меньшего размера, тогда да, ему пришлось бы рассмотреть другие вещи. - person Steve Jessop; 12.11.2012

realloc = Alloc, затем скопируйте, а затем освободите другое решение, выделенное и бесплатное, только наверняка быстрее

person Ibrahim    schedule 10.11.2012

Я бы пошел дальше и поверил, что реализация перераспределения сделает все правильно. Также в будущем вам не следует беспокоиться о том, перемещена ли память, перераспределена и т. Д. В таком виде упреждающей оптимизации нет необходимости, поскольку большая часть времени будет тратиться на переключение контекста из пространства пользователя в пространство ядра.

person enjoylife    schedule 10.11.2012
comment
Если я использую free (), а затем malloc () - могу ли я 2 раза переключаться из пользовательского пространства в пространство ядра? Или здесь компилятор выполняет какую-то оптимизацию? - person HelloWorld; 11.11.2012
comment
Я не уверен, что компилятор сможет оптимизировать два таких отдельных вызова функций. Однако реализация перераспределения почти наверняка будет иметь логику, которая эффективно обрабатывает ваш сценарий. - person enjoylife; 11.11.2012
comment
Но дело в том, что то, что нужно для перераспределения, не подходит для OP. OP не заботится о содержимом памяти, а функция realloc предназначена для бережного сохранения содержимого. Доверять распределителю, чтобы он делал правильные вещи в этом случае, означает вызывать free и malloc. - person user4815162342; 11.11.2012
comment
Обычно при вызове free нет системного вызова. При вызове malloc есть два случая, когда выполняется системный вызов: куча, которую обрабатывает библиотека, слишком мала, и библиотека запрашивает больше с вызовом sbrk, или выделение слишком велико для начала, тогда библиотека напрямую вызовет memmap. В большинстве случаев malloc не является системным вызовом. - person Patrick Schlüter; 11.11.2012