Лучше ли выделять память на двоих? - PullRequest
40 голосов
/ 07 июля 2010

Когда мы используем malloc() для выделения памяти, мы должны дать размер, который находится в степени двух? Или мы просто даем точный размер, который нам нужен?
Как

//char *ptr= malloc( 200 ); 
char *ptr= malloc( 256 );//instead of 200 we use 256

Если лучше дать размер, который находится в степени двух, то для чего это нужно? Почему это лучше?

Спасибо

Редактировать

Причиной моего замешательства является следующая цитата из блога Джоэла Назад к основам

Умные программисты минимизируют потенциальное нарушение malloc всегда выделяя блоки памяти которые имеют степень 2 в размере. Вы знать, 4 байта, 8 байтов, 16 байтов, 18446744073709551616 байт и т. Д. Для причины, которые должны быть интуитивно понятны любой, кто играет с лего, это минимизирует количество странных фрагментация, которая происходит в свободном цепь. Хотя может показаться так впустую пространство, это также легко увидеть как это никогда не тратит впустую больше чем 50% космос. Так что ваша программа не использует более чем в два раза больше памяти, чем необходимо, что не так уж и велико дело.

Извините, я должен был опубликовать приведенную выше цитату ранее. Мои извинения!

Большинство ответов пока говорят, что выделение памяти в степени двух - плохая идея, тогда в каком сценарии лучше следовать точке зрения Джоэла о malloc()? Почему он это сказал? Вышеуказанное предложение устарело сейчас?

Пожалуйста, объясните это.
Спасибо

Ответы [ 11 ]

0 голосов
/ 07 июля 2010

Если вы выделяете какой-то расширяемый буфер, в котором вам нужно выбрать какое-то число для начального распределения, тогда да, степени 2 - это хорошие числа для выбора.Если вам нужно выделить память для struct foo, тогда просто malloc (sizeof (struct foo)).Рекомендация для распределений степени 2 вытекает из неэффективности внутренней фрагментации, но современные реализации malloc, предназначенные для многопроцессорных систем, начинают использовать локальные пулы ЦП для распределений, достаточно малых для этого, чтобы предотвратить конфликт блокировки, который использовался длярезультат, когда несколько потоков будут пытаться выполнять malloc одновременно и тратить больше времени на блокировку из-за фрагментации.

Распределяя только то, что вам нужно, вы гарантируете, что структуры данных более плотно упакованы в памяти, что улучшает кэшчастота попаданий, которая оказывает гораздо большее влияние на производительность, чем внутренняя фрагментация.Существуют сценарии с очень старыми реализациями malloc и очень высокопроизводительными многопроцессорными системами, в которых явное заполнение распределений может обеспечить ускорение, но в этом случае ваши ресурсы будут лучше потрачены на лучшую реализацию malloc и запуск в этой системе.Предварительное заполнение также делает ваш код менее переносимым и не позволяет пользователю или системе выбирать поведение malloc во время выполнения, программно или с переменными среды.

Преждевременная оптимизация - корень всех зол.

...