Комментарии 5
Пока не понятно, в чем состоит "разгон". Все приемы, что приведены с статье - интересны с архитектурной точки зрения и "правильности" построения кода. Но все эти приемы не устраняют основные причины замедления при работе с блоками памяти.
Проблемы с выделением и освобождением памяти в с++ примерно такие:
В мультипоточной среде, если используется одна куча памяти (heap), то в своих операциях она использует средства синхронизации ОС. Т.о. если потоков много, то они начинают "ждать" друг-друга, поскольку операции выделения, освобождения и перераспределения размера блока не очень быстрые (особенно в драйверах). Также, если они должны учесть выравнивание выделенного блока на определенную границу. Для избежания этого можно делать несколько куч. Главное - не запутаться в них. Система управления кучами - здесь бы помогла. Т.е. по какому принципу их разделять, когда создавать, какого размера и т.д.
Любая куча быстро замусоривается/фрагментируется, если в ней происходит работа с разного размера блоками. Попытка использования такого блока в операциях выделения и изменения размера приводит к увеличению задержек в п.1. Какая-то необычная структура кучи могла бы повысить скорость работы с ней.
Стандартные средства синхронизации ОС, используемые в куче (критическая секция, мьютекс) НЕ гарантируют доступ к ресурсу в порядке какой-то очередности. Т.е. если конкурентных потоков очень много, то один из первых запросов может ждать захвата ресурса О-О-очень долго (по меркам процессора и даже профайлера).
Сборщик "мусора" в с++ - традиционная головная боль, если начинаешь хоть как-то сам управлять этими кучами. умные указатели гарантируют лишь своевременное освобождение ресурса. Дефрагментацией приходится заниматься либо в момент освобождения блока (что существенно замедляет операцию освобождения), либо отдельным процессом, который тоже лочит всю кучу и мешает другим потокам с ней работать.
Ну, что-то такое.
Извините, но статья больше похожа на "в С++ есть интерфейс для аллокаторов, выглядит вот так, можно делать разные прикольные штуки"
Вот библиотека с кастомными аллокаторами, там в ридми в разы больше информации - 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, показал логи аллокации (аллилуя!!)
Почему так сложна😩
Разгоняем C++ с кастомными аллокаторами