std::pmr::monotonic_buffer_resource
Definido en el archivo de encabezado <memory_resource>
|
||
class monotonic_buffer_resource : public std::pmr::memory_resource; |
(desde C++17) | |
La clase std::pmr::monotonic_buffer_resource
es una clase de recurso de memoria de propósito especial que libera la memoria asignada solamente cuando el recurso se destruye. Está diseñado para asignaciones de memoria muy rápidas en situaciones en las que la memoria se usa para construir algunos objetos y luego se libera de una vez.
monotonic_buffer_resource
se puede construir con un búfer inicial. Si no hay búfer inicial, o si el búfer está agotado, se obtienen búferes adicionales de un asignador río arriba suministrado en la construcción. El tamaño de los búferes obtenidos sigue una progresión geométrica.
monotonic_buffer_resource
no es seguro frente a hilos.
Contenido |
[editar] Funciones miembro
Construye un objeto monotonic_buffer_resource . (función miembro pública) | |
[virtual] |
Destruye un objeto monotonic_buffer_resource , y libera toda la memoria asignada. (función miembro virtual pública) |
operator= [eliminada] |
El operador de asignación de copia está eliminado. monotonic_buffer_resource no es asignable por copia. (función miembro pública) |
Funciones miembro públicas | |
Libera toda la memoria asignada. (función miembro pública) | |
Devuelve un puntero al recurso de memoria río arriba. (función miembro pública) | |
Funciones miembro protegidas | |
[virtual] |
Asigna memoria. (función miembro virtual protegida) |
[virtual] |
No-operación. (función miembro virtual protegida) |
[virtual] |
Se compara por igualdad con otro std::pmr::memory_resource. (función miembro virtual protegida) |
[editar] Ejemplo
El programa mide el tiempo de creación de enormes listas doblemente enlazadas utilizando los siguientes asignadores:
- el asignador estándar por defecto,
- el asignador
pmr
por defecto, - el asignador
pmr
con recurso monotónico pero sin búfer de memoria explícito, - el asignador
pmr
con recurso monotónico y búfer de memoria externa (en la pila).
#include <list> #include <array> #include <chrono> #include <cstddef> #include <iomanip> #include <iostream> #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<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<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; // suficiente para caber // en todos los nodos std::pmr::monotonic_buffer_resource mbr{buffer.data(), buffer.size()}; std::pmr::polymorphic_allocator<int> pa{&mbr}; 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 (asignador std por defecto): " << t1 << " sec; t1/t1: " << t1/t1 << '\n' << "t2 (asignador pmr por defecto): " << t2 << " sec; t1/t2: " << t1/t2 << '\n' << "t3 (asignador pmr sin búfer ): " << t3 << " sec; t1/t3: " << t1/t3 << '\n' << "t4 (asignador pmr y búfer ): " << t4 << " sec; t1/t4: " << t1/t4 << '\n'; }
Posible salida:
t1 (asignador std por defecto): 0.720 sec; t1/t1: 1.000 t2 (asignador pmr por defecto): 0.915 sec; t1/t2: 0.787 t3 (asignador pmr sin búfer ): 0.370 sec; t1/t3: 1.945 t4 (asignador pmr y búfer ): 0.247 sec; t1/t4: 2.914