track peak allocations

pages
Brett 2024-09-02 03:08:03 -04:00
parent 55f5b5bc05
commit 433002bb8c
5 changed files with 66 additions and 16 deletions

View File

@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.25) cmake_minimum_required(VERSION 3.25)
project(blt-gp VERSION 0.1.41) project(blt-gp VERSION 0.1.42)
include(CTest) include(CTest)
@ -16,7 +16,7 @@ set(CMAKE_CXX_STANDARD 17)
set(THREADS_PREFER_PTHREAD_FLAG ON) set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED) find_package(Threads REQUIRED)
#SET(CMAKE_CXX_FLAGS_RELEASE "-O3 -g") SET(CMAKE_CXX_FLAGS_RELEASE "-O3 -g")
if (NOT TARGET BLT) if (NOT TARGET BLT)
add_subdirectory(lib/blt) add_subdirectory(lib/blt)

View File

@ -140,20 +140,27 @@ int main()
BLT_PRINT_PROFILE("Symbolic Regression", blt::PRINT_CYCLES | blt::PRINT_THREAD | blt::PRINT_WALL); BLT_PRINT_PROFILE("Symbolic Regression", blt::PRINT_CYCLES | blt::PRINT_THREAD | blt::PRINT_WALL);
#ifdef BLT_TRACK_ALLOCATIONS #ifdef BLT_TRACK_ALLOCATIONS
BLT_TRACE("Total Allocations: %ld times with a total of %s", blt::gp::tracker.getAllocations(), BLT_TRACE("Total Allocations: %ld times with a total of %s, peak allocated bytes %s", blt::gp::tracker.getAllocations(),
blt::byte_convert_t(blt::gp::tracker.getAllocatedBytes()).convert_to_nearest_type().to_pretty_string().c_str()); blt::byte_convert_t(blt::gp::tracker.getAllocatedBytes()).convert_to_nearest_type().to_pretty_string().c_str(),
blt::byte_convert_t(blt::gp::tracker.getPeakAllocatedBytes()).convert_to_nearest_type().to_pretty_string().c_str());
auto crossover_calls_v = blt::gp::crossover_calls.get_calls(); auto crossover_calls_v = blt::gp::crossover_calls.get_calls();
auto crossover_allocations_v = blt::gp::crossover_allocations.get_calls(); auto crossover_allocations_v = blt::gp::crossover_allocations.get_calls();
auto mutation_calls_v = blt::gp::mutation_calls.get_calls(); auto mutation_calls_v = blt::gp::mutation_calls.get_calls();
auto mutation_allocations_v = blt::gp::mutation_allocations.get_calls(); auto mutation_allocations_v = blt::gp::mutation_allocations.get_calls();
auto reproduction_calls_v = blt::gp::reproduction_calls.get_calls(); auto reproduction_calls_v = blt::gp::reproduction_calls.get_calls();
auto reproduction_allocations_v = blt::gp::reproduction_allocations.get_calls(); auto reproduction_allocations_v = blt::gp::reproduction_allocations.get_calls();
BLT_TRACE("Total Crossover Calls: %ld", crossover_calls_v); BLT_TRACE("Total Crossover Calls: %ld Peak Bytes Allocated %s", crossover_calls_v,
BLT_TRACE("Total Mutation Calls: %ld", mutation_calls_v); blt::byte_convert_t(blt::gp::crossover_calls.get_value()).convert_to_nearest_type().to_pretty_string().c_str());
BLT_TRACE("Total Reproduction Calls: %ld", reproduction_calls_v); BLT_TRACE("Total Mutation Calls: %ld Peak Bytes Allocated %s", mutation_calls_v,
BLT_TRACE("Total Crossover Allocations: %ld Bytes %s", crossover_allocations_v, blt::byte_convert_t(blt::gp::crossover_allocations.get_value()).convert_to_nearest_type().to_pretty_string().c_str()); blt::byte_convert_t(blt::gp::mutation_calls.get_value()).convert_to_nearest_type().to_pretty_string().c_str());
BLT_TRACE("Total Mutation Allocations: %ld Bytes %s", mutation_allocations_v, blt::byte_convert_t(blt::gp::mutation_allocations.get_value()).convert_to_nearest_type().to_pretty_string().c_str()); BLT_TRACE("Total Reproduction Calls: %ld Peak Bytes Allocated %s", reproduction_calls_v,
BLT_TRACE("Total Reproduction Allocations: %ld Bytes %s", reproduction_allocations_v, blt::byte_convert_t(blt::gp::reproduction_allocations.get_value()).convert_to_nearest_type().to_pretty_string().c_str()); blt::byte_convert_t(blt::gp::reproduction_calls.get_value()).convert_to_nearest_type().to_pretty_string().c_str());
BLT_TRACE("Total Crossover Allocations: %ld Bytes %s", crossover_allocations_v,
blt::byte_convert_t(blt::gp::crossover_allocations.get_value()).convert_to_nearest_type().to_pretty_string().c_str());
BLT_TRACE("Total Mutation Allocations: %ld Bytes %s", mutation_allocations_v,
blt::byte_convert_t(blt::gp::mutation_allocations.get_value()).convert_to_nearest_type().to_pretty_string().c_str());
BLT_TRACE("Total Reproduction Allocations: %ld Bytes %s", reproduction_allocations_v,
blt::byte_convert_t(blt::gp::reproduction_allocations.get_value()).convert_to_nearest_type().to_pretty_string().c_str());
BLT_TRACE("Percent Crossover calls allocate? %lf%%", BLT_TRACE("Percent Crossover calls allocate? %lf%%",
static_cast<double>(crossover_allocations_v) / static_cast<double>(crossover_calls_v == 0 ? 1 : crossover_calls_v) * 100); static_cast<double>(crossover_allocations_v) / static_cast<double>(crossover_calls_v == 0 ? 1 : crossover_calls_v) * 100);
BLT_TRACE("Percent Mutation calls allocate? %lf%%", BLT_TRACE("Percent Mutation calls allocate? %lf%%",

View File

@ -102,6 +102,7 @@ namespace blt::gp
#ifdef BLT_TRACK_ALLOCATIONS #ifdef BLT_TRACK_ALLOCATIONS
tracker.stop_measurement_thread_local(state); tracker.stop_measurement_thread_local(state);
crossover_calls.call(); crossover_calls.call();
crossover_calls.set_value(std::max(crossover_calls.get_value(), state.getAllocatedByteDifference()));
if (state.getAllocatedByteDifference() != 0) if (state.getAllocatedByteDifference() != 0)
{ {
crossover_allocations.call(state.getAllocatedByteDifference()); crossover_allocations.call(state.getAllocatedByteDifference());
@ -125,6 +126,7 @@ namespace blt::gp
#ifdef BLT_TRACK_ALLOCATIONS #ifdef BLT_TRACK_ALLOCATIONS
tracker.stop_measurement_thread_local(state); tracker.stop_measurement_thread_local(state);
mutation_calls.call(); mutation_calls.call();
mutation_calls.set_value(std::max(mutation_calls.get_value(), state.getAllocatedByteDifference()));
if (state.getAllocationDifference() != 0) if (state.getAllocationDifference() != 0)
{ {
mutation_allocations.call(state.getAllocatedByteDifference()); mutation_allocations.call(state.getAllocatedByteDifference());
@ -144,6 +146,7 @@ namespace blt::gp
#ifdef BLT_TRACK_ALLOCATIONS #ifdef BLT_TRACK_ALLOCATIONS
tracker.stop_measurement_thread_local(state); tracker.stop_measurement_thread_local(state);
reproduction_calls.call(); reproduction_calls.call();
reproduction_calls.set_value(std::max(reproduction_calls.get_value(), state.getAllocatedByteDifference()));
if (state.getAllocationDifference() != 0) if (state.getAllocationDifference() != 0)
{ {
reproduction_allocations.call(state.getAllocatedByteDifference()); reproduction_allocations.call(state.getAllocatedByteDifference());

View File

@ -27,6 +27,7 @@
#include <string> #include <string>
#include <mutex> #include <mutex>
#include <atomic> #include <atomic>
#include <condition_variable>
namespace blt::gp namespace blt::gp
{ {
@ -72,6 +73,9 @@ namespace blt::gp
blt::hashmap_t<std::thread::id, std::unique_ptr<blt::u64>> deallocations; blt::hashmap_t<std::thread::id, std::unique_ptr<blt::u64>> deallocations;
blt::hashmap_t<std::thread::id, std::unique_ptr<blt::u64>> allocated_bytes; blt::hashmap_t<std::thread::id, std::unique_ptr<blt::u64>> allocated_bytes;
blt::hashmap_t<std::thread::id, std::unique_ptr<blt::u64>> deallocated_bytes; blt::hashmap_t<std::thread::id, std::unique_ptr<blt::u64>> deallocated_bytes;
std::mutex mutex;
std::condition_variable var;
}; };
struct allocation_data_t struct allocation_data_t
@ -111,17 +115,39 @@ namespace blt::gp
void reserve() void reserve()
{ {
std::scoped_lock lock(mutex); {
tl.allocations[std::this_thread::get_id()] = std::make_unique<blt::u64>(); std::scoped_lock lock(tl.mutex);
tl.deallocations[std::this_thread::get_id()] = std::make_unique<blt::u64>(); tl.allocations.insert({std::this_thread::get_id(), std::make_unique<blt::u64>()});
tl.allocated_bytes[std::this_thread::get_id()] = std::make_unique<blt::u64>(); tl.deallocations.insert({std::this_thread::get_id(), std::make_unique<blt::u64>()});
tl.deallocated_bytes[std::this_thread::get_id()] = std::make_unique<blt::u64>(); tl.allocated_bytes.insert({std::this_thread::get_id(), std::make_unique<blt::u64>()});
tl.deallocated_bytes.insert({std::this_thread::get_id(), std::make_unique<blt::u64>()});
}
tl.var.notify_all();
}
blt::size_t reserved_threads()
{
return tl.allocations.size();
}
void await_completion(blt::u64 required_threads)
{
std::unique_lock lock(tl.mutex);
tl.var.wait(lock, [this, required_threads]() {
return reserved_threads() == required_threads;
});
} }
void allocate(blt::size_t bytes) void allocate(blt::size_t bytes)
{ {
allocations++; allocations++;
allocated_bytes += bytes; allocated_bytes += bytes;
auto diff = getCurrentlyAllocatedBytes();
auto atomic_val = peak_allocated_bytes.load(std::memory_order_relaxed);
while (diff > atomic_val &&
!peak_allocated_bytes.compare_exchange_weak(atomic_val, diff, std::memory_order_relaxed, std::memory_order_relaxed));
add_map(tl.allocations, 1); add_map(tl.allocations, 1);
add_map(tl.allocated_bytes, bytes); add_map(tl.allocated_bytes, bytes);
} }
@ -164,6 +190,11 @@ namespace blt::gp
return getAllocatedBytes() - getDeallocatedBytes(); return getAllocatedBytes() - getDeallocatedBytes();
} }
[[nodiscard]] blt::u64 getPeakAllocatedBytes() const
{
return peak_allocated_bytes;
}
allocation_tracker_t::tl_t& get_thread_local() allocation_tracker_t::tl_t& get_thread_local()
{ {
return tl; return tl;
@ -230,7 +261,7 @@ namespace blt::gp
std::atomic_uint64_t allocated_bytes = 0; std::atomic_uint64_t allocated_bytes = 0;
std::atomic_uint64_t deallocated_bytes = 0; std::atomic_uint64_t deallocated_bytes = 0;
std::mutex mutex; std::atomic_uint64_t peak_allocated_bytes = 0;
}; };
class call_tracker_t class call_tracker_t
@ -259,6 +290,11 @@ namespace blt::gp
secondary_value += value; secondary_value += value;
} }
void set_value(blt::u64 value)
{
secondary_value = value;
}
void call() void call()
{ {
primary_calls++; primary_calls++;

View File

@ -69,6 +69,7 @@ namespace blt::gp
thread_helper.threads.emplace_back(new std::thread([i, this]() { thread_helper.threads.emplace_back(new std::thread([i, this]() {
#ifdef BLT_TRACK_ALLOCATIONS #ifdef BLT_TRACK_ALLOCATIONS
tracker.reserve(); tracker.reserve();
tracker.await_completion(config.threads);
#endif #endif
std::function<void(blt::size_t)>* execution_function = nullptr; std::function<void(blt::size_t)>* execution_function = nullptr;
while (!should_thread_terminate()) while (!should_thread_terminate())
@ -89,5 +90,8 @@ namespace blt::gp
} }
})); }));
} }
#ifdef BLT_TRACK_ALLOCATIONS
tracker.await_completion(config.threads);
#endif
} }
} }