home | help
std::pmr::m...fer_resource(3)  C++ Standard Libary std::pmr::m...fer_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  mem-
     ory resource
	class  that  releases the allocated memory only when the resource is de-
     stroyed. 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.  monoto-
     nic_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_re-
     source
	[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 <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; // 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

http://cppreference.com 	   2024.06.10	   std::pmr::m...fer_resource(3)

home | help