Espacios de nombres
Variantes
Acciones

std::pmr::monotonic_buffer_resource

De cppreference.com
< cpp‎ | memory
 
 
Gestión de memoria dinámica
Punteros inteligentes
(C++11)
(C++11)
(C++11)
(hasta C++17)
(C++11)
(C++23)
Asignadores de memoria
Recursos de memoria
pmr::monotonic_buffer_resource
(C++17)
Almacenamiento no inicializado
Algoritmos de memoria no inicializada
Algoritmos restringidos de memoria no inicializada
Apoyo para recolección de basura
(C++11)(hasta C++23)
(C++11)(hasta C++23)
(C++11)(hasta C++23)
(C++11)(hasta C++23)
(C++11)(hasta C++23)
(C++11)(hasta C++23)
Misceláneos
(C++20)
(C++11)
(C++11)
 
 
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) [editar]
[virtual]
Destruye un objeto monotonic_buffer_resource, y libera toda la memoria asignada.
(función miembro virtual pública) [editar]
operator=
[eliminada]
El operador de asignación de copia está eliminado. monotonic_buffer_resource no es asignable por copia.
(función miembro pública) [editar]
Funciones miembro públicas
Libera toda la memoria asignada.
(función miembro pública) [editar]
Devuelve un puntero al recurso de memoria río arriba.
(función miembro pública) [editar]
Funciones miembro protegidas
[virtual]
Asigna memoria.
(función miembro virtual protegida) [editar]
No-operación.
(función miembro virtual protegida) [editar]
[virtual]
Se compara por igualdad con otro std::pmr::memory_resource.
(función miembro virtual protegida) [editar]

[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