Created
August 18, 2020 21:04
-
-
Save arrieta/d1f303d2a6c003685bd600fcac0c033a to your computer and use it in GitHub Desktop.
Example Polymorphic Memory Resource (std::pmr) Monotonic Buffer Resource
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Example Polymorphic Memory Resource (std::pmr) Monotonic Buffer Resource. | |
// J. Arrieta, Nabla Zero Labs | |
// | |
// * Pre-allocate two buffers, one with space for 2 chars and one with space for 256 chars. | |
// * Filled pre-allocated buffers with underscores to peek into them later and see where memory was touched. | |
// * Create two monotonic_buffer_resources, one for each buffer. | |
// * Notice that the main pool receives a pointer to the "backup" pool. | |
// * Create a vector of char that uses the main memory resource. | |
// * Push back on the vector all chars from 'a' to 'z'. | |
// * See how the first char was allocated using the first memory resource (pool). | |
// * Subsequent pushbacks relied on the back-up memory resource. | |
// * The vector contains the correct data. | |
// * If `backup` is smaller (try), the vector would have started allocating on the heap. | |
#include <memory_resource> | |
#include <memory> | |
#include <vector> | |
#include <algorithm> | |
#include <iostream> | |
#include <numeric> | |
int main() { | |
auto buffer_size = 2; | |
auto backup_size = 256; | |
auto buffer = std::make_unique<char[]>(buffer_size); | |
auto backup = std::make_unique<char[]>(backup_size); | |
std::fill_n(buffer.get(), buffer_size, '_'); | |
std::fill_n(backup.get(), backup_size, '_'); | |
auto upst = std::pmr::monotonic_buffer_resource(backup.get(), backup_size); | |
auto pool = std::pmr::monotonic_buffer_resource(buffer.get(), buffer_size, &upst); | |
std::pmr::vector<char> v(&pool); | |
for (auto c = 'a'; c <= 'z'; ++c) { | |
v.push_back(c); | |
} | |
std::cout << "main buffer contents:\n"; | |
std::for_each_n(buffer.get(), buffer_size, [idx=0] (auto x) mutable { std::cout << (idx++) << " " << x << "\n";}); | |
std::cout << "backup buffer contents:\n"; | |
std::for_each_n(backup.get(), backup_size, [idx=0] (auto x) mutable { std::cout << (idx++) << " " << x << "\n";}); | |
std::cout << "vector contents:\n"; | |
std::for_each(v.begin(), v.end(), [idx=0] (auto x) mutable { std::cout << (idx++) << " " << x << "\n";}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Idea: create a
monotonic_buffer_resource
backed by a memory map of (essentially) infinite size (all in virtual memory). As a result, we would have astd::pmr::vector
with pointer stability (after callingreserve
on the maximum size). Virtual memory ensures that memory will be ready to go when needed, but won't actually page it to RAM until then.