std::pmr:: monotonic_buffer_resource
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Public member functions | ||||
| Protected member functions | ||||
|
Определено в заголовочном файле
<memory_resource>
|
||
|
class
monotonic_buffer_resource
:
public
std::
pmr
::
memory_resource
;
|
(начиная с C++17) | |
Класс
std::pmr::monotonic_buffer_resource
является специализированным классом ресурса памяти, который освобождает выделенную память только при уничтожении ресурса. Он предназначен для очень быстрого выделения памяти в ситуациях, когда память используется для создания нескольких объектов и затем освобождается целиком.
monotonic_buffer_resource
может быть создан с начальным буфером. Если начальный буфер отсутствует или его ресурс исчерпан, дополнительные буферы запрашиваются из
upstream memory resource
, предоставленного при создании. Размер получаемых буферов следует геометрической прогрессии.
monotonic_buffer_resource
не является потокобезопасным.
Содержание |
Функции-члены
создает
monotonic_buffer_resource
(публичная функция-член) |
|
|
[virtual]
|
уничтожает
monotonic_buffer_resource
, освобождая всю выделенную память
(виртуальная публичная функция-член) |
|
operator=
[deleted]
|
оператор копирующего присваивания удален.
monotonic_buffer_resource
не поддерживает копирующее присваивание
(публичная функция-член) |
Публичные функции-члены |
|
|
освободить всю выделенную память
(публичная функция-член) |
|
|
возвращает указатель на вышестоящий ресурс памяти
(публичная функция-член) |
|
Защищенные функции-члены |
|
|
[virtual]
|
выделить память
(виртуальная защищенная функция-член) |
|
[virtual]
|
пустая операция
(виртуальная защищенная функция-член) |
|
[virtual]
|
сравнить на равенство с другим
std::pmr::memory_resource
(виртуальная защищенная функция-член) |
Пример
Программа измеряет время создания больших двусвязных списков с использованием следующих аллокаторов:
- стандартный аллокатор по умолчанию,
-
аллокатор
pmrпо умолчанию, -
pmrаллокатор с монотонным ресурсом, но без явного буфера памяти, -
pmrаллокатор с монотонным ресурсом и внешним буфером памяти (в стеке).
#include <array> #include <chrono> #include <cstddef> #include <iomanip> #include <iostream> #include <list> #include <memory_resource> template<typename Func> auto benchmark(Func test_func, int iterations) { const auto start = std::chrono::system_clock::now(); while (iterations-- > 0) test_func(); const auto stop = std::chrono::system_clock::now(); const auto secs = std::chrono::duration<double>(stop - start); return secs.count(); } int main() { constexpr int iterations{100}; constexpr int total_nodes{2'00'000}; auto default_std_alloc = [total_nodes] { std::list<int> list; for (int i{}; i != total_nodes; ++i) list.push_back(i); }; auto default_pmr_alloc = [total_nodes] { std::pmr::list (Примечание: В данном случае переводить нечего, так как весь текст состоит из HTML-тегов, атрибутов и C++ специфичных терминов (std::pmr::list), которые согласно инструкциям не подлежат переводу. Сохранена исходная структура без изменений.)<int> list; for (int i{}; i != total_nodes; ++i) list.push_back(i); }; auto pmr_alloc_no_buf = [total_nodes] { std::pmr::monotonic_buffer_resource mbr; std::pmr::polymorphic_allocator<int> pa{&mbr}; std::pmr::list (Примечание: В данном случае переводить нечего, так как весь текст состоит из HTML-тегов, атрибутов и C++ специфичных терминов (std::pmr::list), которые согласно инструкциям не подлежат переводу. Сохранена исходная структура и форматирование.)<int> list{pa}; for (int i{}; i != total_nodes; ++i) list.push_back(i); }; auto pmr_alloc_and_buf = [total_nodes] { std::array<std::byte, total_nodes * 32> buffer; // достаточно для размещения всех узлов std::pmr::monotonic_buffer_resource mbr{buffer.data(), buffer.size()}; std::pmr::polymorphic_allocator<int> pa{&mbr}; std::pmr::list (Примечание: В данном случае переводить нечего, так как весь текст состоит из HTML-тегов, атрибутов и C++ специфичных терминов (std::pmr::list), которые согласно инструкциям не подлежат переводу. Сохранена исходная структура без изменений.)<int> list{pa}; for (int i{}; i != total_nodes; ++i) list.push_back(i); }; const double t1 = benchmark(default_std_alloc, iterations); const double t2 = benchmark(default_pmr_alloc, iterations); const double t3 = benchmark(pmr_alloc_no_buf , iterations); const double t4 = benchmark(pmr_alloc_and_buf, iterations); std::cout << std::fixed << std::setprecision(3) << "t1 (по умолчанию std alloc): " << t1 << " сек; t1/t1: " << t1/t1 << '\n' << "t2 (по умолчанию pmr аллокатор): " << t2 << " сек; t1/t2: " << t1/t2 << '\n' << "t3 (pmr аллокатор без буфера): " << t3 << " сек; t1/t3: " << t1/t3 << '\n' << "t4 (pmr аллокатор и буфер): " << t4 << " сек; t1/t4: " << t1/t4 << '\n'; }
Возможный вывод:
t1 (default std alloc): 0.720 сек; t1/t1: 1.000 t2 (default pmr alloc): 0.915 сек; t1/t2: 0.787 t3 (pmr alloc no buf): 0.370 сек; t1/t3: 1.945 t4 (pmr alloc and buf): 0.247 сек; t1/t4: 2.914