Есть ли хорошие C ++ для C ++, которые максимизируют местность ссылок - PullRequest
5 голосов
/ 20 мая 2009

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

В идеале распределитель помещает все в непрерывный блок памяти. (Я думаю, это иногда называют ареной?)

Я не могу использовать плоский вектор, потому что выделенные объекты полиморфны.

Какие у меня варианты?

Ответы [ 7 ]

5 голосов
/ 20 мая 2009

Просто сделай свой.

Смотрите мой старый вопрос, чтобы узнать, как вы можете начать:

Усовершенствования для этого распределителя стека C ++?

4 голосов
/ 20 мая 2009

Поскольку вы не заботитесь о перераспределении, вы можете использовать линейный распределитель. Выделите огромное количество памяти заранее и сохраните указатель на начало. malloc (x) перемещает указатель выделения вперед на x байтов и возвращает старое значение указателя, delete (x) заглушается. Как упомянуто здесь, другой плакат уже имеет имплиментацию

Распределения располагаются настолько близко, насколько это возможно, выделения выполняются невероятно быстро, и память возвращается в порядке распределения. Когда симуляция завершена, вы просто сбрасываете указатель распределителя на начало памяти и очищаете все имеющиеся у вас указатели извне распределителя на объекты внутри него.

Распределители пулов - отличный выбор, если вы хотите удалять объекты быстрее, чем куча, но не будете упаковывать ваши данные в память так близко и не так быстро. Используйте boost: pool для тех. Это отличный выбор для игр, если у вас есть х байт для хранения, скажем, уровня, и вы готовы выбросить все вместе в одно и то же время.

Кроме того, если вас интересует производительность памяти, см. Что должен знать каждый программист о памяти - PDF . Он охватывает такие вещи, как локальность ссылки и ее влияние на производительность. В частности, вы можете создать пул для каждого типа объектов, которые используются вместе, или объявить ваши объекты как структуру массивов, а не как массив структур

2 голосов
/ 20 мая 2009

Как насчет Boost.Pool?

1 голос
/ 20 мая 2009

Интерфейсы и реализации C Дейва Хэнсона включают очень хороший распределитель на основе арены. Если память служит, метаданные не хранятся вместе с объектами, и они выделяются из смежного свободного пространства, так что это примерно столько, сколько вы можете надеяться.

1 голос
/ 20 мая 2009

Набор фиксированных блоков работает довольно хорошо и имеет очень привлекательную лицензию (MIT).

1 голос
/ 20 мая 2009

Обычный метод - фиксированное распределение блоков. См .: Леа , Робинсон , Ноултон , Грюнвальд .

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

Если вы заранее не знаете, насколько большим будет содержимое объекта, вы можете написать распределитель пула, который выделяет память последовательно; т.е. это гарантирует

Foo *a = new Foo();
Bar *b = new Bar;
b == ((byte *)(a)) + sizeof(Foo);

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

0 голосов
/ 20 мая 2009

Это довольно большой предмет, просто возьмите википедию . Один конкретный пример был в книге Александреску и должен быть реализован в его библиотеке Локи . GCC также поставляется с несколькими реализациями std::allocator, просто посмотрите в ваш дистрибутив.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...