Как стать автором
Обновить

Комментарии 5

Пока не понятно, в чем состоит "разгон". Все приемы, что приведены с статье - интересны с архитектурной точки зрения и "правильности" построения кода. Но все эти приемы не устраняют основные причины замедления при работе с блоками памяти.

Проблемы с выделением и освобождением памяти в с++ примерно такие:

  1. В мультипоточной среде, если используется одна куча памяти (heap), то в своих операциях она использует средства синхронизации ОС. Т.о. если потоков много, то они начинают "ждать" друг-друга, поскольку операции выделения, освобождения и перераспределения размера блока не очень быстрые (особенно в драйверах). Также, если они должны учесть выравнивание выделенного блока на определенную границу. Для избежания этого можно делать несколько куч. Главное - не запутаться в них. Система управления кучами - здесь бы помогла. Т.е. по какому принципу их разделять, когда создавать, какого размера и т.д.

  2. Любая куча быстро замусоривается/фрагментируется, если в ней происходит работа с разного размера блоками. Попытка использования такого блока в операциях выделения и изменения размера приводит к увеличению задержек в п.1. Какая-то необычная структура кучи могла бы повысить скорость работы с ней.

  3. Стандартные средства синхронизации ОС, используемые в куче (критическая секция, мьютекс) НЕ гарантируют доступ к ресурсу в порядке какой-то очередности. Т.е. если конкурентных потоков очень много, то один из первых запросов может ждать захвата ресурса О-О-очень долго (по меркам процессора и даже профайлера).

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

Ну, что-то такое.

Извините, но статья больше похожа на "в С++ есть интерфейс для аллокаторов, выглядит вот так, можно делать разные прикольные штуки"
Вот библиотека с кастомными аллокаторами, там в ридми в разы больше информации - https://github.com/mtrebi/memory-allocators

Тема select_on_container_copy_construction и propagate_on_container_copy_assignment не раскрыта)

Ну и странно, что про Allocator Traits не рассказали... Ну ладно, допустим, что это детали.

А почему у Вас PoolAllocator имеет копирующий конструктор, но при этом не клонируется пул, а копируется указатель? Мы так к дабл-фри придём очень быстро.

Статья не полная без std::pmr::...

Попробовал запустить пример с LoggingAllocator на https://godbolt.org:

1) gcc 14.1 вообще не хочет компилировать (с учётом добавления #include <vector>)

2) gcc 11.2 скомпилировал, ничего не вывел

3) установил стандарт с++17, ничего не вывел

4) установил стандарт с++20, показал логи аллокации (аллилуя!!)

Почему так сложна😩

Зарегистрируйтесь на Хабре, чтобы оставить комментарий