Краткая справка:
Я разрабатываю систему, которая должна работать месяцами, и использую динамическое распределение.
Вопрос:
Я слышал, что фрагментация памяти замедляется new
а также malloc
операторы, потому что им нужно «найти» место в одной из «дыр», которые я оставил в памяти, вместо того, чтобы просто «идти вперед» в куче.
Я прочитал следующий вопрос:
Что такое фрагментация памяти?
Но ни в одном из ответов не упоминалось ничего о производительности, только сбой при выделении больших кусков памяти.
Так что фрагментация памяти делает new
занять больше времени, чтобы выделить память?
Если да, на сколько? Как я знаю, если new
испытывает ли «трудное время» поиск памяти в куче?
Я попытался найти, какие структуры данных / алгоритмы использует GCC, чтобы найти «дыру» в памяти для размещения внутри. Но не смог найти никакого объяснения спуска.
Распределение памяти зависит от платформы, в зависимости от платформы.
Я бы сказал «Да, new
занимает время, чтобы выделить память. Сколько времени зависит от многих факторов, таких как алгоритм, уровень фрагментации, скорость процессора, оптимизации и т. Д.
Лучший ответ на то, сколько времени занято, это профилировать и измерить. Напишите простую программу, которая фрагментирует память, а затем измеряет время для выделения памяти.
Для программы не существует прямого способа выяснить сложность поиска доступных областей памяти. Вы можете прочитать часы, выделить память и снова прочитать. Другая идея — установить таймер.
Примечание: во многих встроенных системах динамическое распределение памяти не одобряется. В критических системах фрагментация может быть врагом. Поэтому используются массивы фиксированного размера. Распределение памяти фиксированного размера (во время компиляции) устраняет фрагментацию как проблему дефекта.
Редактировать 1: Поиск
Обычно для выделения памяти требуется вызов функции. Это приводит к тому, что процессору может потребоваться перезагрузить кэш или конвейер команд, что потребует дополнительного времени на обработку. Также могут быть дополнительные инструкции для передачи параметров, таких как минимальный размер. Локальные переменные и выделения во время компиляции обычно не требуют вызова функции для выделения.
Если алгоритм распределения не является линейным (например, доступ к массиву), он потребует шагов для поиска доступного слота. Некоторые алгоритмы управления памятью используют разные стратегии в зависимости от требуемого размера. Например, некоторые диспетчеры памяти могут иметь отдельные пулы для размеров от 64 бит или меньше.
Если вы считаете, что диспетчер памяти имеет связанный список блоков, диспетчеру потребуется найти первый блок, размер которого больше или равен размеру запроса. Если блок больше запрашиваемого размера, он может быть разделен, а оставшаяся память затем создается в новый блок и добавляется в список.
Не существует стандартного алгоритма управления памятью. Они различаются в зависимости от потребностей системы. Диспетчеры памяти для платформ с ограниченными (небольшими) размерами памяти будут отличаться от тех, которые имеют большой объем памяти. Выделение памяти для критических систем может отличаться от выделения для некритических систем. Стандарт C ++ не требует поведение менеджера памяти, только некоторые требования. Например, диспетчеру памяти разрешено выделяться с жесткого диска или сетевого устройства.
Значимость воздействия зависит от алгоритма выделения памяти. Лучший способ — это измерить производительность на вашей целевой платформе.
Других решений пока нет …