Управление памятью в интенсивно использующем память приложении

К сожалению, в CMake нет способа запросить диапазон стандартов.

Тогда единственный способ (который я использовал в прошлом) - использовать, например, check_cxx_compiler_flag проверить для -std=c++20, -std=c++17, -std=c++14 и -std=c++11 (в этом порядке) и использовать самое высокое с, например target_compile_options .

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

7
задан dmckee 23 January 2009 в 20:11
поделиться

8 ответов

Я думаю, что Ваш лучший выбор не состоит в том, чтобы реализовать тот, пока профили не доказывают, что CRT фрагментирует память способом, которая повреждает производительность Вашего приложения. CRT, базовая ОС и парни STL проводят много времени, думая об управлении памятью.

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

Другое преимущество ожидания до профиля, который шоу, это - проблема, - то, что Вы будете также знать, зафиксировали ли Вы на самом деле что-нибудь. Это - самая важная часть производительности, фиксируют.

Пока Вы используете стандартные классы набора algorihtmns (такие как STL/повышение), не должно быть очень трудно включить новое средство выделения позже в цикле для фиксации частей кодовой базы, которые действительно должны быть зафиксированы. Очень маловероятно, что Вам будет нужно кодированное средство выделения руки для Вашей всей программы.

38
ответ дан 6 December 2019 в 04:50
поделиться

Это был SmartHeap от MicroQuill?

2
ответ дан 6 December 2019 в 04:50
поделиться

Раньше была превосходная сторонняя общедоступная заменяющая библиотека "кучи" для VC ++, но я больше не помню имя. Наше приложение получило 30%-е ускорение, когда мы начали использовать его.

Править: это - SmartHeap - спасибо, ChrisW

2
ответ дан 6 December 2019 в 04:50
поделиться

Вы решили записать своего собственного диспетчера памяти для выделения памяти от виртуального адресного пространства, или Вы позволяете CRT брать на себя управление и делать управление памятью для Вас?

Стандартная библиотека часто достаточно хороша. Если это не затем, вместо того, чтобы заменить его, меньший шаг должен переопределить operator new и operator delete для определенных классов, не для всех классов.

1
ответ дан 6 December 2019 в 04:50
поделиться

На основе моего опыта фрагментация является главным образом проблемой, когда Вы непрерывно выделяете и освобождаете большие буферы (как по 16k), так как это - те, которые в конечном счете вызовут из памяти, если "куча" не может найти достаточно большое место для одного из них.

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

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

2
ответ дан 6 December 2019 в 04:50
поделиться

Это зависит очень от Ваших шаблонов выделения памяти. От моего личного опыта обычно существуют один или два класса в проекте, для которого нужны особые условия когда дело доходит до управления памятью, потому что они часто используются в части кода, где Вы проводите много времени. Могли бы также быть классы, которому в некотором конкретном контексте нужен специальный режим, но в других контекстах может использоваться, не беспокоясь об этом.

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

Это некоторые общие вещи думать о:

Во-первых, маленькие объекты это выделяется и уничтожается, быстро должен быть помещен на стек. Самое быстрое выделение - те, которые никогда не делаются. Выделение стека также сделано без любой блокировки глобальной "кучи", которая хороша для многопоточного кода. Выделение на "куче" в c/c ++ может быть относительно дорогим по сравнению с языками GC как Java, так старайтесь избегать его, если Вам не нужен он.

Если Вы делаете большое выделение, необходимо быть осторожными с поточной обработкой производительности. Классическая ловушка является строковыми классами, который имеет тенденцию делать большое выделение, скрытое пользователю. Если Вы делаете большую строковую обработку в нескольких потоках, они могли бы закончить тем, что боролись о взаимном исключении в коде "кучи". С этой целью брать под свой контроль управление памятью может ускорить вещи много. Переключение на другую реализацию "кучи" обычно является не решением здесь, так как "куча" все еще будет глобальна, и Ваши потоки будут бороться об этом. Я думаю, что Google имеет "кучу", которая должна быть быстрее в многопоточных средах все же. Не попробовали его самостоятельно.

1
ответ дан 6 December 2019 в 04:50
поделиться

нет, я не был бы.

Возможности того, что я писал лучший код затем CRT с, кто знает, сколько сотни года человека, который инвестируют в него, являются тонкими.

Я искал бы специализированную библиотеку вместо изобретения велосипед.

0
ответ дан 6 December 2019 в 04:50
поделиться

Хотя большинство из вас указывает, что вы не должны писать свой собственный менеджер памяти, он все еще может быть полезен, если:

  • у вас есть конкретное требование или ситуация, в которой вы уверены, что вы можете написать более быструю версию
  • Вы хотите написать вам собственную логику Memory-Overrrite (чтобы помочь в отладке)
  • Вы хотите отслеживать места, где память утечка

, если вы хотите написать свой собственный менеджер памяти, важно разделить его в Следующие 4 части:

  1. Часть, которую «перехватывает» вызовы на Malloc / Free (C) и New / Delete (C ++). Это довольно просто для новых / удаления (просто глобальные новые и удаления операторов), но и для Malloc / Free это возможно («перезаписать» функции CRT, переопределенные звонки в Malloc / Free, ...)
  2. Часть, которая представляет точку входа вашего менеджера памяти, и который вызывается частью «перехватчика»
  3. , часть, которая реализует фактический менеджер памяти. Возможно, у вас будет несколько реализаций этого (в зависимости от ситуации)
  4. часть, которую «украшает» выделенную память с информацией о стеке вызовов, перезаписи-зоны (aka Red Zones), ...

, если они 4 части четко разделены, также становится легко заменить одну деталь на другую или добавить новую часть к ней, например:

  • Добавление Memory Manager Реализация библиотеки блоков строительства протектора Intel (для части 3)
  • 1 Чтобы поддержать новую версию компилятора, новую платформу или совершенно новый компилятор

, написав менеджер памяти, я могу только указать, что он может быть удобным, имеющим простой способ расширить свой собственный менеджер памяти. Например. То, что я регулярно должен сделать, это найти утечки памяти в длительноми серверными приложениями. С моим собственным менеджером памяти я делаю это так:

  • Запустите приложение и дайте ему «прогреться» на некоторое время
  • Спросите свой собственный менеджер памяти, чтобы сбросить обзор используемой памяти, включая стеки вызова в Момент вызова
  • Продолжить выполнение приложения
  • Сделайте второй дамп
  • Сортировать два свалка в алфавитном порядке в стеке вызовов
  • Посмотрите на различия

, хотя вы можете сделать подобные вещи без Компоненты коробки, они имеют тенденцию иметь некоторые недостатки:

  • часто они серьезно замедляют приложение
  • часто, часто они могут сообщать только утечки в конце приложения, а также приложение

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

4
ответ дан 6 December 2019 в 04:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: