From 16ee4ff65b00742c9b572fa61e116ba5fb5d4d1c Mon Sep 17 00:00:00 2001 From: Hirek193 Date: Fri, 23 Oct 2026 22:45:49 +0200 Subject: [PATCH] perf(debug): live heap blocks by size and the objects of the simulation tables in the memory section of the debug panel --- rendering/opengl46/opengl46renderer.cpp | 34 +++++++++++++++++++++++++ utilities/memorystats.cpp | 29 ++++++++++++++++++--- utilities/memorystats.h | 5 ++++ 3 files changed, 65 insertions(+), 3 deletions(-) diff --git a/rendering/opengl46/opengl46renderer.cpp b/rendering/opengl46/opengl46renderer.cpp index cc00ae9e..4fae1d55 100644 --- a/rendering/opengl46/opengl46renderer.cpp +++ b/rendering/opengl46/opengl46renderer.cpp @@ -18,6 +18,9 @@ http://mozilla.org/MPL/2.0/. #include "model/MdlMngr.h" #include "audio/audiorenderer.h" #include "world/Track.h" +#include "world/Traction.h" +#include "world/MemCell.h" +#include "audio/sound.h" #include "utilities/memorystats.h" #include "utilities/Logs.h" #include "simulation/simulationtime.h" @@ -1178,6 +1181,25 @@ void opengl46_renderer::Update_Memory_Info() auto const heap { query_heap_memory() }; text += "taken with new: " + mb( heap.bytes ) + " in " + std::to_string( heap.blocks ) + " blocks" + ( process.valid && ( process.committed > heap.bytes ) ? ", the rest of the private memory " + mb( process.committed - heap.bytes ) + " (drivers, libraries)" : std::string{} ) + "\n"; + // the same by the size of the blocks, in wider ranges + { + struct range { std::size_t last; char const *name; }; // classes up to last, see heap_memory + static range const ranges[] = { + { 6, "below 64 B" }, { 8, "64-255 B" }, { 10, "256 B-1 KB" }, { 12, "1-4 KB" }, { 16, "4-64 KB" }, { 20, "64 KB-1 MB" }, { 24, "1-16 MB" }, { heap_memory::CLASSES - 1, "16 MB and more" } }; + std::size_t first { 0 }; + text += " by block size:"; + for( auto const &item : ranges ) { + std::uint64_t bytes { 0 }, blocks { 0 }; + for( auto index { first }; index <= item.last; ++index ) { + bytes += heap.classbytes[ index ]; + blocks += heap.classblocks[ index ]; + } + first = item.last + 1; + if( blocks == 0 ) { continue; } + text += std::string( " " ) + item.name + ": " + mb( bytes ) + " in " + std::to_string( blocks ) + ";"; + } + text += "\n"; + } // the memory of the card, all processes: GL_NVX_gpu_memory_info (in kB) if( m_nvxmemory < 0 ) { m_nvxmemory = 0; @@ -1252,6 +1274,18 @@ void opengl46_renderer::Update_Memory_Info() accounted += sounds.bytes; text += "sounds: " + counted( sounds, "buffers" ) + " " + mb( sounds.bytes ) + "\n"; text += "vehicles: " + std::to_string( simulation::Vehicles.sequence().size() ) + "\n"; + // the objects of the tables of the simulation, without what they hold + { + auto const table = [ & ]( char const *Name, std::size_t const Count, std::size_t const Size ) { + return std::string( Name ) + " " + std::to_string( Count ) + " (" + mb( static_cast( Count ) * Size ) + ")"; }; + auto const tables { + table( "tracks", simulation::Paths.sequence().size(), sizeof( TTrack ) ) + ", " + + table( "traction", simulation::Traction.sequence().size(), sizeof( TTraction ) ) + ", " + + table( "memory cells", simulation::Memory.sequence().size(), sizeof( TMemCell ) ) + ", " + + table( "instances in the table", simulation::Instances.sequence().size(), sizeof( TAnimModel ) ) + ", " + + table( "sounds", simulation::Sounds.sequence().size(), sizeof( sound_source ) ) }; + text += "tables: " + tables + "\n"; + } if( process.valid ) { auto const total { process.committed > 0 ? process.committed : process.resident }; text += "counted above: " + mb( accounted ) + " of " + mb( total ) + ( process.committed > 0 ? " private" : " resident" ) + ", the rest " diff --git a/utilities/memorystats.cpp b/utilities/memorystats.cpp index a889c170..3f35bff8 100644 --- a/utilities/memorystats.cpp +++ b/utilities/memorystats.cpp @@ -11,6 +11,7 @@ http://mozilla.org/MPL/2.0/. #include "utilities/memorystats.h" #include +#include #include #include @@ -34,6 +35,14 @@ namespace std::atomic g_heapbytes{0}; std::atomic g_heapblocks{0}; +// by the size of the blocks, see heap_memory +std::array, heap_memory::CLASSES> g_classbytes{}; +std::array, heap_memory::CLASSES> g_classblocks{}; + +std::size_t size_class(std::size_t const Size) +{ + return std::min(std::bit_width(Size), heap_memory::CLASSES - 1); +} std::size_t block_size(void *Block) { @@ -56,8 +65,11 @@ void *counted_new(std::size_t Size) { if (auto *block{std::malloc(Size)}) { - g_heapbytes.fetch_add(block_size(block), std::memory_order_relaxed); + auto const size{block_size(block)}; + g_heapbytes.fetch_add(size, std::memory_order_relaxed); g_heapblocks.fetch_add(1, std::memory_order_relaxed); + g_classbytes[size_class(size)].fetch_add(size, std::memory_order_relaxed); + g_classblocks[size_class(size)].fetch_add(1, std::memory_order_relaxed); return block; } auto const handler{std::get_new_handler()}; @@ -75,8 +87,11 @@ void counted_delete(void *Block) noexcept { return; } - g_heapbytes.fetch_sub(block_size(Block), std::memory_order_relaxed); + auto const size{block_size(Block)}; + g_heapbytes.fetch_sub(size, std::memory_order_relaxed); g_heapblocks.fetch_sub(1, std::memory_order_relaxed); + g_classbytes[size_class(size)].fetch_sub(size, std::memory_order_relaxed); + g_classblocks[size_class(size)].fetch_sub(1, std::memory_order_relaxed); std::free(Block); } @@ -148,7 +163,15 @@ void operator delete[](void *Block, std::nothrow_t const &) noexcept heap_memory query_heap_memory() { - return {g_heapbytes.load(std::memory_order_relaxed), g_heapblocks.load(std::memory_order_relaxed)}; + heap_memory result; + result.bytes = g_heapbytes.load(std::memory_order_relaxed); + result.blocks = g_heapblocks.load(std::memory_order_relaxed); + for (std::size_t index = 0; index < heap_memory::CLASSES; ++index) + { + result.classbytes[index] = g_classbytes[index].load(std::memory_order_relaxed); + result.classblocks[index] = g_classblocks[index].load(std::memory_order_relaxed); + } + return result; } process_memory query_process_memory() diff --git a/utilities/memorystats.h b/utilities/memorystats.h index d2ec3731..0358126e 100644 --- a/utilities/memorystats.h +++ b/utilities/memorystats.h @@ -9,6 +9,7 @@ http://mozilla.org/MPL/2.0/. #pragma once +#include #include #include @@ -29,6 +30,10 @@ struct heap_memory { std::uint64_t bytes{0}; std::uint64_t blocks{0}; + // the same by the size of the blocks: class N holds the blocks of 2^(N-1) to 2^N - 1 bytes + static constexpr std::size_t CLASSES{48}; + std::array classbytes{}; + std::array classblocks{}; }; heap_memory query_heap_memory();