Namespaces
Variants

std::pmr:: monotonic_buffer_resource

From cppreference.net
Memory management library
( exposition only* )
Allocators
Uninitialized memory algorithms
Constrained uninitialized memory algorithms
Memory resources
Uninitialized storage (until C++20)
( until C++20* )
( until C++20* )
( until C++20* )

Garbage collector support (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
Definiert im Header <memory_resource>
class monotonic_buffer_resource : public std:: pmr :: memory_resource ;
(seit C++17)

Die Klasse std::pmr::monotonic_buffer_resource ist eine spezielle Speicherressourcenklasse, die den allokierten Speicher nur freigibt, wenn die Ressource zerstört wird. Sie ist für sehr schnelle Speicherallokationen in Situationen vorgesehen, in denen Speicher zum Aufbau einiger Objekte verwendet wird und dann auf einmal freigegeben wird.

monotonic_buffer_resource kann mit einem anfänglichen Puffer konstruiert werden. Falls kein anfänglicher Puffer vorhanden ist oder der Puffer erschöpft ist, werden zusätzliche Puffer von einem upstream memory resource bezogen, das bei der Konstruktion bereitgestellt wird. Die Größe der bezogenen Puffer folgt einer geometrischen Progression.

monotonic_buffer_resource ist nicht threadsicher.

Inhaltsverzeichnis

Memberfunktionen

konstruiert einen monotonic_buffer_resource
(öffentliche Elementfunktion)
[virtual]
zerstört einen monotonic_buffer_resource und gibt allen allokierten Speicher frei
(virtuelle öffentliche Elementfunktion)
operator=
[deleted]
Kopierzuweisungsoperator ist gelöscht. monotonic_buffer_resource ist nicht kopierzuweisbar
(öffentliche Elementfunktion)
Öffentliche Elementfunktionen
gibt allen allokierten Speicher frei
(öffentliche Elementfunktion)
gibt einen Zeiger auf die vorgelagerte Speicherressource zurück
(öffentliche Elementfunktion)
Geschützte Elementfunktionen
[virtual]
allokiert Speicher
(virtuelle geschützte Elementfunktion)
[virtual]
No-Op (keine Operation)
(virtuelle geschützte Elementfunktion)
[virtual]
vergleicht auf Gleichheit mit einem anderen std::pmr::memory_resource
(virtuelle geschützte Elementfunktion)

Beispiel

Das Programm misst die Zeit zur Erstellung umfangreicher doppelt verketteter Listen unter Verwendung der folgenden Allokatoren:

  • Standard-Allokator (Standard),
  • Standard- pmr -Allokator,
  • pmr -Allokator mit monotoner Ressource aber ohne expliziten Speicherpuffer,
  • pmr -Allokator mit monotoner Ressource und externem Speicherpuffer (auf dem Stack).
#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
**Erklärung:**
- HTML-Tags und Attribute wurden unverändert beibehalten
- C++-spezifische Begriffe (`std::chrono::system_clock::now`) wurden nicht übersetzt
- Die ursprüngliche Formatierung wurde vollständig erhalten
- Die Link-Struktur bleibt funktional identisch();
    while (iterations-- > 0)
        test_func();
    const auto stop = std::chrono::system_clock::now
**Erklärung:**
- HTML-Tags und Attribute wurden unverändert beibehalten
- C++-spezifische Begriffe (`std::chrono::system_clock::now`) wurden nicht übersetzt
- Die ursprüngliche Formatierung wurde vollständig erhalten
- Die Link-Struktur bleibt funktional identisch();
    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; // ausreichend, um alle Knoten aufzunehmen
        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 << " Sek.; t1/t1: " << t1/t1 << '\n'
              << "t2 (Standard-PMR-Allokator): " << t2 << " Sek.; t1/t2: " << t1/t2 << '\n'
              << "t3 (pmr alloc  no buf): " << t3 << " sec; t1/t3: " << t1/t3 << '\n'
              << "t4 (pmr alloc und buf): " << t4 << " Sek.; t1/t4: " << t1/t4 << '\n';
}

Mögliche Ausgabe:

t1 (default std alloc): 0.720 Sek.; t1/t1: 1.000
t2 (default pmr alloc): 0.915 Sek.; t1/t2: 0.787
t3 (pmr alloc  no buf): 0.370 Sek.; t1/t3: 1.945
t4 (pmr alloc and buf): 0.247 Sek.; t1/t4: 2.914