std::pmr:: monotonic_buffer_resource
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Public member functions | ||||
| Protected member functions | ||||
|
Défini dans l'en-tête
<memory_resource>
|
||
|
class
monotonic_buffer_resource
:
public
std::
pmr
::
memory_resource
;
|
(depuis C++17) | |
La classe
std::pmr::monotonic_buffer_resource
est une classe de ressource mémoire à usage spécial qui libère la mémoire allouée uniquement lorsque la ressource est détruite. Elle est conçue pour des allocations mémoire très rapides dans des situations où la mémoire est utilisée pour construire quelques objets puis est libérée en une seule fois.
monotonic_buffer_resource
peut être construit avec un tampon initial. S'il n'y a pas de tampon initial, ou si le tampon est épuisé, des tampons supplémentaires sont obtenus d'une
ressource mémoire amont
fournie lors de la construction. La taille des tampons obtenus suit une progression géométrique.
monotonic_buffer_resource
n'est pas thread-safe.
Table des matières |
Fonctions membres
construit une
monotonic_buffer_resource
(fonction membre publique) |
|
|
[virtuel]
|
détruit une
monotonic_buffer_resource
, libérant toute la mémoire allouée
(fonction membre publique virtuelle) |
|
operator=
[supprimé]
|
l'opérateur d'affectation par copie est supprimé.
monotonic_buffer_resource
n'est pas copiable par affectation
(fonction membre publique) |
Fonctions membres publiques |
|
|
libère toute la mémoire allouée
(fonction membre publique) |
|
|
retourne un pointeur vers la ressource mémoire amont
(fonction membre publique) |
|
Fonctions membres protégées |
|
|
[virtuel]
|
alloue de la mémoire
(fonction membre protégée virtuelle) |
|
[virtuel]
|
opération sans effet
(fonction membre protégée virtuelle) |
|
[virtuel]
|
compare pour l'égalité avec une autre
std::pmr::memory_resource
(fonction membre protégée virtuelle) |
Exemple
Le programme mesure le temps de création de listes doublement chaînées volumineuses en utilisant les allocateurs suivants :
- allocateur standard par défaut,
-
allocateur
pmrpar défaut, -
allocateur
pmravec ressource monotone mais sans tampon mémoire explicite, -
allocateur
pmravec ressource monotone et tampon mémoire externe (sur la pile).
#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; // suffisant pour contenir tous les nœuds 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 (allocateur std par défaut) : " << t1 << " sec; t1/t1: " << t1/t1 << '\n' << "t2 (allocateur pmr par défaut) : " << t2 << " sec; t1/t2: " << t1/t2 << '\n' << "t3 (pmr alloc no buf): " << t3 << " sec; t1/t3: " << t1/t3 << '\n' << "t4 (pmr alloc et buf): " << t4 << " sec; t1/t4: " << t1/t4 << '\n'; }
Sortie possible :
t1 (alloc std par défaut) : 0.720 sec ; t1/t1 : 1.000 t2 (alloc pmr par défaut) : 0.915 sec ; t1/t2 : 0.787 t3 (alloc pmr sans buf) : 0.370 sec ; t1/t3 : 1.945 t4 (alloc pmr avec buf) : 0.247 sec ; t1/t4 : 2.914