| std::pmr::monotonic_buffer_resource(3) | C++ Standard Libary | std::pmr::monotonic_buffer_resource(3) | 
NAME¶
std::pmr::monotonic_buffer_resource - std::pmr::monotonic_buffer_resource
Synopsis¶
 Defined in header <memory_resource>
  
   class monotonic_buffer_resource : public std::pmr::memory_resource; (since
    C++17)
  
   The class std::pmr::monotonic_buffer_resource is a special-purpose memory
    resource
  
   class that releases the allocated memory only when the resource is destroyed.
    It is
  
   intended for very fast memory allocations in situations where memory is used
    to
  
   build up a few objects and then is released all at once.
  
   monotonic_buffer_resource can be constructed with an initial buffer. If there
    is no
  
   initial buffer, or if the buffer is exhausted, additional buffers are
    obtained from
  
   an upstream memory resource supplied at construction. The size of buffers
    obtained
  
   follows a geometric progression.
  
   monotonic_buffer_resource is not thread-safe.
Member functions¶
 constructor Constructs a monotonic_buffer_resource
  
   (public member function)
  
   destructor Destroys a monotonic_buffer_resource, releasing all allocated
  
   [virtual] memory
  
   (virtual public member function)
  
   operator= Copy assignment operator is deleted. monotonic_buffer_resource is
  
   [deleted] not copy assignable
  
   (public member function)
Public member functions¶
 release Release all allocated memory
  
   (public member function)
  
   upstream_resource Returns a pointer to the upstream memory resource
  
   (public member function)
Protected member functions¶
 do_allocate Allocate memory
  
   [virtual] (virtual protected member function)
  
   do_deallocate No-op
  
   [virtual] (virtual protected member function)
  
   do_is_equal Compare for equality with another std::pmr::memory_resource
  
   [virtual] (virtual protected member function)
Example¶
 The program measures the time of creating huge double-linked
    lists using the
  
   following allocators:
  
   * default standard allocator,
  
   * default pmr allocator,
  
   * pmr allocator with monotonic resource but without explicit memory buffer,
  
   * pmr allocator with monotonic resource and external memory buffer (on
    stack).
// Run this code
  
   #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; // enough to fit in all
    nodes
  
   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 (default std alloc): " << t1 << "
    sec; t1/t1: " << t1/t1 << '\n'
  
   << "t2 (default pmr alloc): " << t2 << "
    sec; t1/t2: " << t1/t2 << '\n'
  
   << "t3 (pmr alloc no buf): " << t3 << " sec;
    t1/t3: " << t1/t3 << '\n'
  
   << "t4 (pmr alloc and buf): " << t4 << "
    sec; t1/t4: " << t1/t4 << '\n';
  
   }
Possible output:¶
 t1 (default std alloc): 0.720 sec; t1/t1: 1.000
  
   t2 (default pmr alloc): 0.915 sec; t1/t2: 0.787
  
   t3 (pmr alloc no buf): 0.370 sec; t1/t3: 1.945
  
   t4 (pmr alloc and buf): 0.247 sec; t1/t4: 2.914
| 2022.07.31 | http://cppreference.com |