std::pmr:: monotonic_buffer_resource
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Public member functions | ||||
| Protected member functions | ||||
|
Definido en el 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 solo cuando se destruye el recurso. Está diseñada para asignaciones de memoria muy rápidas en situaciones donde la memoria se utiliza para construir algunos objetos y luego se libera toda de una vez.
monotonic_buffer_resource
puede construirse con un búfer inicial. Si no hay búfer inicial, o si el búfer se agota, se obtienen búferes adicionales de un
recurso de memoria ascendente
suministrado durante la construcción. El tamaño de los búferes obtenidos sigue una progresión geométrica.
monotonic_buffer_resource
no es seguro para subprocesos.
Contenidos |
Funciones miembro
construye un
monotonic_buffer_resource
(función miembro pública) |
|
|
[virtual]
|
destruye un
monotonic_buffer_resource
, liberando toda la memoria asignada
(función miembro pública virtual) |
|
operator=
[deleted]
|
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 ascendente
(función miembro pública) |
|
Funciones miembro protegidas |
|
|
[virtual]
|
asigna memoria
(función miembro protegida virtual) |
|
[virtual]
|
sin operación
(función miembro protegida virtual) |
|
[virtual]
|
compara para igualdad con otro
std::pmr::memory_resource
(función miembro protegida virtual) |
Ejemplo
El programa mide el tiempo de creación de enormes listas doblemente enlazadas utilizando los siguientes asignadores de memoria:
- asignador estándar predeterminado,
-
asignador
pmrpredeterminado, -
pmrasignador con recurso monótono pero sin búfer de memoria explícito, -
pmrasignador con recurso monótono y búfer de memoria externo (en pila).
#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<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 contener 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 (allocador std predeterminado): " << t1 << " seg; t1/t1: " << t1/t1 << '\n' << "t2 (asignador pmr predeterminado): " << t2 << " seg; t1/t2: " << t1/t2 << '\n' << "t3 (pmr alloc no buf): " << t3 << " seg; t1/t3: " << t1/t3 << '\n' << "t4 (pmr alloc and buf): " << t4 << " seg; t1/t4: " << t1/t4 << '\n'; }
Salida posible:
t1 (default std alloc): 0.720 seg; t1/t1: 1.000 t2 (default pmr alloc): 0.915 seg; t1/t2: 0.787 t3 (pmr alloc no buf): 0.370 seg; t1/t3: 1.945 t4 (pmr alloc and buf): 0.247 seg; t1/t4: 2.914