0

I am trying to investigate the cause of the difference in performance between the two allocators, as shown in https://en.cppreference.com/w/cpp/memory/monotonic_buffer_resource. What I have found so far:

  • In GCC, it seems that the default pmr allocator uses monotonic_buffer_resource but not the std allocator, according to compiler explorer.
  • I looked into the source code of the header files and libstdc++, but could not find how monotonic_buffer_resource was selected to be used by the default pmr allocator.
  • From my reading of the source code, it seems that std::pmr::new_delete_resource() should be used, and that should make default std allocator and default pmr allocator the same, but obviously it is not.
void default_pmr_alloc() {
    std::pmr::list<int> list; // uses monotonic_buffer_resource
    for (int i{}; i != total_nodes; ++i) {
        list.push_back(i);
    }
}

void default_std_alloc() {
    std::list<int> list; // uses operator new/delete
    for (int i{}; i != total_nodes; ++i) {
        list.push_back(i);
    }
}
ggg
  • 1,857
  • 2
  • 21
  • 33
  • At no point did you ask a question... – ChrisMM Oct 21 '22 at 18:34
  • @ChrisMM good point, changed the title – ggg Oct 21 '22 at 18:40
  • Are you building with optimizations turned on? If no, the reason might be the same as in [this](https://stackoverflow.com/q/72061267/3740047) post. – Sedenion Oct 22 '22 at 06:29
  • @Sedenion yes, `-O3`, see the compiler explorer link, https://godbolt.org/z/7YMqz3Mab – ggg Oct 22 '22 at 16:28
  • Looking at some documentation with sample output is not investigating a performance difference, and neither is reading the compiler output for a program that doesn't run anything and which you never executed. Do you have some specific benchmark code that you executed and that showed some results? What were the results? Currently I can't even tell what you're claiming without following a link. – Useless Oct 23 '22 at 21:53
  • @Useless the benchmarks are shown in https://en.cppreference.com/w/cpp/memory/monotonic_buffer_resource – ggg Oct 24 '22 at 14:13
  • No, the documentation lists some "possible output". I don't know how it was compiled or executed or on what platform. You're making an assumption based on sample output instead of executing a benchmark, which is the only way to see whether your figures are actually reproducible. As a bonus, once you have a reproducible benchmark, you'll also have an actual question. – Useless Oct 24 '22 at 16:32

1 Answers1

2

It does indeed use new_delete_resource. (which from std::pmr::get_default_resource())


you can check it by

list.get_allocator().resource()->is_equal(*std::pmr::new_delete_resource()); // true

https://godbolt.org/z/qGTG57MfY


Not sure about what the benchmark is, but type erasure comes with it's own penalty, pmr one would probably be slower.

apple apple
  • 10,292
  • 2
  • 16
  • 36
  • Interesting, I noticed that once I comment away that return statement, `monotonic_buffer_resource` appear in the generated assembly again. – ggg Oct 24 '22 at 17:27
  • The benchmark is at https://en.cppreference.com/w/cpp/memory/monotonic_buffer_resource. std::pmr is faster there – ggg Oct 24 '22 at 17:28
  • @ggg the test seems pretty reasonable afaict https://godbolt.org/z/TsGWr5vGE. default allocator is faster than pmr default (which has virtual call cost). – apple apple Oct 24 '22 at 17:41
  • @ggg even comment out return, the typeid still indicate it's `new_delete_resource` https://godbolt.org/z/Paf9hPo4c – apple apple Oct 24 '22 at 17:43
  • @ggg I'd guess the `monotonic_buffer_resource` name is some optimization by compiler in case it's indeed one. – apple apple Oct 24 '22 at 17:47
  • @ggg and indeed it appears even though no `list` is constructed https://godbolt.org/z/cncT8Mj95 – apple apple Oct 24 '22 at 17:48
  • @ggg wait, you say pmr is faster, but pmr takes `0.915s` while native takes only `0.720s`? (cppreference) – apple apple Oct 24 '22 at 17:57
  • thanks for checking. As to how `monotonic_buffer_resource` appears in the code for `std::pmr` containers. I will create a new question for that in the future. – ggg Oct 24 '22 at 17:58
  • just noticed my mistake, default std allocator is faster than pmr allocator – ggg Oct 24 '22 at 17:59
  • @ggg fwiw, just using `allocate` is enough to make compiler generate it https://godbolt.org/z/z7sxaoE3v (with optimize) – apple apple Oct 24 '22 at 18:07
  • you have piqued my curiosity, I dug into the source code but couldn't find anything, will post a new question for that. – ggg Oct 24 '22 at 19:05
  • https://stackoverflow.com/questions/74185797/why-does-monotonic-buffer-resource-appear-in-the-assembly-when-it-doesnt-seem – ggg Oct 24 '22 at 19:16