Skip to content

Instantly share code, notes, and snippets.

@ribomation
Created January 18, 2024 14:03
Show Gist options
  • Save ribomation/39e7b78d01560176253346d509cb79f5 to your computer and use it in GitHub Desktop.
Save ribomation/39e7b78d01560176253346d509cb79f5 to your computer and use it in GitHub Desktop.
Memory size estimation of std::pmr container
#include <iostream>
#include <string_view>
#include <array>
#include <unordered_map>
#include "memory-mapped-file.hxx"
#include "measurement.hxx"
#include "aggregation.hxx"
#include "util.hxx"
#include "spy-pmr.hxx"
namespace rm = ribomation::util;
namespace io = ribomation::io;
namespace br = ribomation::brc;
namespace pm = ribomation::pmr;
using std::cout;
int main(int argc, char** argv) {
auto filename = rm::getFilename(argc, argv);
cout << "filename: " << filename << "\n----\n";
auto file = io::MemoryMappedFile{filename};
auto chunk = file.data();
cout << "loaded " << chunk.size() * 1E-6 << " MB, from " << filename << "\n";
using Result = std::pmr::unordered_map<std::string_view, br::Aggregation>;
{
constexpr auto SIZE = 100'000;
cout << "heap size: " << SIZE << " bytes\n";
auto storage = std::array<unsigned char, SIZE>{};
auto buffer = pm::SpyBuffer{storage.data(), storage.size(), std::pmr::null_memory_resource()};
auto heap = pm::SpyHeap{&buffer};
auto result = Result{&heap};
result.reserve(500);
auto start = 0UL;
while (start < chunk.size()) {
auto m = br::extract(chunk, start);
result[m.station] += m.temperature;
}
}
}
#pragma once
#include <iostream>
#include <memory_resource>
namespace ribomation::pmr {
struct SpyHeap : std::pmr::unsynchronized_pool_resource {
using super = std::pmr::unsynchronized_pool_resource;
unsigned long currentBytes{};
unsigned long maxBytes{};
explicit SpyHeap(memory_resource* upstream) : super(upstream) {}
~SpyHeap() override { std::cout << *this << "\n"; }
friend auto operator<<(std::ostream& os, SpyHeap const& h) -> std::ostream& {
return os << "[SPY-HEAP] current=" << h.currentBytes << " bytes, max=" << h.maxBytes << " bytes";
}
protected:
void* do_allocate(size_t numBytes, size_t alignment) override {
currentBytes += numBytes;
maxBytes += numBytes;
return super::do_allocate(numBytes, alignment);
}
void do_deallocate(void* ptr, size_t numBytes, size_t alignment) override {
currentBytes -= numBytes;
super::do_deallocate(ptr, numBytes, alignment);
}
};
struct SpyBuffer : std::pmr::monotonic_buffer_resource {
using super = std::pmr::monotonic_buffer_resource;
unsigned long currentBytes{};
unsigned long maxBytes{};
explicit SpyBuffer(void* data, size_t size, memory_resource* upstream) : super(data, size, upstream) {}
~SpyBuffer() override { std::cout << *this << "\n"; }
friend auto operator<<(std::ostream& os, SpyBuffer const& h) -> std::ostream& {
return os << "[SPY-BUF] current=" << h.currentBytes << " bytes, max=" << h.maxBytes << " bytes";
}
protected:
void* do_allocate(size_t numBytes, size_t alignment) override {
currentBytes += numBytes;
maxBytes += numBytes;
return super::do_allocate(numBytes, alignment);
}
void do_deallocate(void* ptr, size_t numBytes, size_t alignment) override {
currentBytes -= numBytes;
super::do_deallocate(ptr, numBytes, alignment);
}
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment