Шэньчжэнь Tianteng промышленности Лтд
You Are Here:Главная > НОВОСТИ > Содержание
Автономный дистрибьютор
Jun 25, 2018

Одной из основных причин определения пользовательского распределителя является повышение производительности. Использование специального специализированного распределителя может улучшить производительность программы или повысить эффективность использования памяти или и то, и другое. Распределитель по умолчанию использует новый оператор для распределения пространства памяти, которое часто реализуется с помощью функции распределения кучи языка C (malloc ()). Поскольку функция распределения кучи часто оптимизирована для распределений пространственной памяти, распределитель по умолчанию обычно эффективен при распределении памяти для контейнеров, которым необходимо одновременно выделять большие объемы памяти (например, vector, deque). Однако для ассоциативных контейнеров и двусвязных списков, которым необходимо часто выделять небольшой объем памяти, если распределитель по умолчанию распределяет память, он обычно неэффективен. Кроме того, распределитель по умолчанию, основанный на malloc (), имеет много проблем, таких как плохая ссылочная локальность, и может вызвать фрагментацию памяти.

В связи с этим в этом случае люди часто используют распределители пула памяти для решения проблемы частых небольших распределений. В отличие от метода «присваивания по требованию» по умолчанию, при использовании распределителя на основе пула памяти программа будет выделять большой объем памяти («пул памяти») заранее, а затем, когда необходимо выделить память, только пользовательский распределитель указатель на память в пуле должен быть возвращен запрашивающему. Когда объект разрушен, нет необходимости фактически освобождать память. Вместо этого реальное освобождение задерживается до конца жизненного цикла пула памяти.

На тему «Пользовательский диспенсер» многие эксперты C ++ и соавторы уже участвовали в обсуждениях, таких как «Эффективный STL» Скотта Мейерса и «Современный дизайн C + +» Андре Александре Реску. Мейерс понимает, что если все экземпляры дозатора для определенного типа Т должны быть равны, экземпляры переносных дозаторов не должны содержать никаких состояний. Хотя стандарт C ++ поощряет разработчиков библиотек к поддержке диспенсеров с сохранением работоспособности, Мейерс сказал, что соответствующие параграфы являются «(выглядит) замечательной точкой зрения», но являются почти пустыми словами и утверждают, что ограничения дистрибьютора «слишком суровы». Например, список STL позволяет использовать метод сплайсинга, т. Е. Узел объекта списка A может перемещаться непосредственно в другой объект списка B. Это требует, чтобы память, выделенная распределителем A, могла быть освобождена распределителем B, тем самым вызывая экземпляры дистрибьютора для A и B должны быть равны. Майерс приходит к выводу, что дистрибьютор лучше всего определяется как тип, который использует статические методы. Например, согласно стандарту C ++, распределители должны предоставить шаблон другого класса, который реализует метод перезаписи.

Кроме того, на «языке программирования C ++ +» Бьяни Струпструп считает, что «« строго ограничивая дистрибьютора, чтобы не различать информацию каждого объекта », это, очевидно, не проблема» (по сути), и это указывается, что большинству дистрибьюторов не требуется состояние, и даже если нет состояния, производительность лучше. Он предложил три варианта использования пользовательских диспенсеров: тип пула памяти, тип разделяемой памяти и тип сбора мусора, а также продемонстрировал реализацию сплиттера с использованием встроенного пула памяти для обеспечения быстроты. Выделите / освободите небольшой объем памяти. Однако он также упомянул, что такая оптимизация может быть реализована в распространителе выборки, который он предоставил.

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