From dd144a199a8a38d25ecb5c2a04042e39082648d7 Mon Sep 17 00:00:00 2001 From: Brett Date: Sat, 31 Aug 2024 23:15:16 -0400 Subject: [PATCH] track allocations --- CMakeLists.txt | 2 +- examples/symbolic_regression.cpp | 39 ++++++++++---------- include/blt/gp/fwdecl.h | 6 ++++ include/blt/gp/selection.h | 43 +++++++++++++++------- include/blt/gp/stats.h | 62 ++++++++++++++++++++++++++++++++ 5 files changed, 119 insertions(+), 33 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1b40123..967684f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.25) -project(blt-gp VERSION 0.1.37) +project(blt-gp VERSION 0.1.38) include(CTest) diff --git a/examples/symbolic_regression.cpp b/examples/symbolic_regression.cpp index 078316e..69eac6d 100644 --- a/examples/symbolic_regression.cpp +++ b/examples/symbolic_regression.cpp @@ -104,35 +104,15 @@ int main() { BLT_TRACE("------------{Begin Generation %ld}------------", program.get_current_generation()); BLT_TRACE("Creating next generation"); - -#ifdef BLT_TRACK_ALLOCATIONS - auto gen_alloc = blt::gp::tracker.start_measurement(); -#endif - BLT_START_INTERVAL("Symbolic Regression", "Gen"); program.create_next_generation(); BLT_END_INTERVAL("Symbolic Regression", "Gen"); - -#ifdef BLT_TRACK_ALLOCATIONS - blt::gp::tracker.stop_measurement(gen_alloc); - BLT_TRACE("Generation Allocated %ld times with a total of %s", gen_alloc.getAllocationDifference(), - blt::byte_convert_t(gen_alloc.getAllocatedByteDifference()).convert_to_nearest_type().to_pretty_string().c_str()); - auto fitness_alloc = blt::gp::tracker.start_measurement(); -#endif - BLT_TRACE("Move to next generation"); BLT_START_INTERVAL("Symbolic Regression", "Fitness"); program.next_generation(); BLT_TRACE("Evaluate Fitness"); program.evaluate_fitness(); BLT_END_INTERVAL("Symbolic Regression", "Fitness"); - -#ifdef BLT_TRACK_ALLOCATIONS - blt::gp::tracker.stop_measurement(fitness_alloc); - BLT_TRACE("Fitness Allocated %ld times with a total of %s", fitness_alloc.getAllocationDifference(), - blt::byte_convert_t(fitness_alloc.getAllocatedByteDifference()).convert_to_nearest_type().to_pretty_string().c_str()); -#endif - BLT_TRACE("----------------------------------------------"); std::cout << std::endl; } @@ -162,6 +142,25 @@ int main() #ifdef BLT_TRACK_ALLOCATIONS BLT_TRACE("Total Allocations: %ld times with a total of %s", blt::gp::tracker.getAllocations(), blt::byte_convert_t(blt::gp::tracker.getAllocatedBytes()).convert_to_nearest_type().to_pretty_string().c_str()); + auto crossover_calls = blt::gp::crossover_calls.get_calls(); + auto crossover_allocations = blt::gp::crossover_allocations.get_calls(); + auto mutation_calls = blt::gp::mutation_calls.get_calls(); + auto mutation_allocation = blt::gp::mutation_allocations.get_calls(); + auto reproduction_calls = blt::gp::reproduction_calls.get_calls(); + auto reproduction_allocation = blt::gp::reproduction_allocations.get_calls(); + BLT_TRACE("Total Crossover Calls: %ld", crossover_calls); + BLT_TRACE("Total Mutation Calls: %ld", mutation_calls); + BLT_TRACE("Total Reproduction Calls: %ld", reproduction_calls); + BLT_TRACE("Total Crossover Allocations: %ld", crossover_allocations); + BLT_TRACE("Total Mutation Allocations: %ld", mutation_allocation); + BLT_TRACE("Total Reproduction Allocations: %ld", reproduction_allocation); + + BLT_TRACE("Percent Crossover calls allocate? %lf%%", + static_cast(crossover_allocations) / static_cast(crossover_calls == 0 ? 1 : crossover_calls) * 100); + BLT_TRACE("Percent Mutation calls allocate? %lf%%", + static_cast(mutation_allocation) / static_cast(mutation_calls == 0 ? 1 : mutation_calls) * 100); + BLT_TRACE("Percent Reproduction calls allocate? %lf%%", + static_cast(reproduction_allocation) / static_cast(reproduction_calls == 0 ? 1 : reproduction_calls) * 100); #endif return 0; diff --git a/include/blt/gp/fwdecl.h b/include/blt/gp/fwdecl.h index 24319e0..8311bac 100644 --- a/include/blt/gp/fwdecl.h +++ b/include/blt/gp/fwdecl.h @@ -29,6 +29,12 @@ namespace blt::gp { inline allocation_tracker_t tracker; + inline call_tracker_t crossover_calls; + inline call_tracker_t mutation_calls; + inline call_tracker_t reproduction_calls; + inline call_tracker_t crossover_allocations; + inline call_tracker_t mutation_allocations; + inline call_tracker_t reproduction_allocations; class gp_program; diff --git a/include/blt/gp/selection.h b/include/blt/gp/selection.h index a3c3856..bf1cc71 100644 --- a/include/blt/gp/selection.h +++ b/include/blt/gp/selection.h @@ -88,7 +88,9 @@ namespace blt::gp // everyone gets a chance once per loop. if (random.choice(config.crossover_chance)) { -// auto state = tracker.start_measurement(); +#ifdef BLT_TRACK_ALLOCATIONS + auto state = tracker.start_measurement(); +#endif // crossover const tree_t* p1; const tree_t* p2; @@ -97,37 +99,54 @@ namespace blt::gp p1 = &crossover_selection.select(program, current_pop); p2 = &crossover_selection.select(program, current_pop); } while (!config.crossover.get().apply(program, *p1, *p2, c1, *c2)); -// tracker.stop_measurement(state); -// BLT_TRACE("Crossover Allocated %ld times with a total of %s", state.getAllocationDifference(), -// blt::byte_convert_t(state.getAllocatedByteDifference()).convert_to_nearest_type().to_pretty_string().c_str()); +#ifdef BLT_TRACK_ALLOCATIONS + tracker.stop_measurement(state); + crossover_calls.call(); + if (state.getAllocationDifference() != 0) + crossover_allocations.call(state.getAllocatedByteDifference()); +#endif return 2; } break; case 1: if (random.choice(config.mutation_chance)) { -// auto state = tracker.start_measurement(); +#ifdef BLT_TRACK_ALLOCATIONS + auto state = tracker.start_measurement(); +#endif // mutation const tree_t* p; do { p = &mutation_selection.select(program, current_pop); } while (!config.mutator.get().apply(program, *p, c1)); -// tracker.stop_measurement(state); -// BLT_TRACE("Mutation Allocated %ld times with a total of %s", state.getAllocationDifference(), -// blt::byte_convert_t(state.getAllocatedByteDifference()).convert_to_nearest_type().to_pretty_string().c_str()); +#ifdef BLT_TRACK_ALLOCATIONS + tracker.stop_measurement(state); + mutation_calls.call(); + if (state.getAllocationDifference() != 0) + { + mutation_allocations.call(state.getAllocatedByteDifference()); + } +#endif return 1; } break; case 2: if (config.reproduction_chance > 0 && random.choice(config.reproduction_chance)) { -// auto state = tracker.start_measurement(); +#ifdef BLT_TRACK_ALLOCATIONS + auto state = tracker.start_measurement(); +#endif // reproduction c1 = reproduction_selection.select(program, current_pop); -// tracker.stop_measurement(state); -// BLT_TRACE("Reproduction Allocated %ld times with a total of %s", state.getAllocationDifference(), -// blt::byte_convert_t(state.getAllocatedByteDifference()).convert_to_nearest_type().to_pretty_string().c_str()); +#ifdef BLT_TRACK_ALLOCATIONS + tracker.stop_measurement(state); + reproduction_calls.call(); + if (state.getAllocationDifference() != 0) + { + reproduction_allocations.call(state.getAllocatedByteDifference()); + } +#endif return 1; } break; diff --git a/include/blt/gp/stats.h b/include/blt/gp/stats.h index 64b3f13..9fda502 100644 --- a/include/blt/gp/stats.h +++ b/include/blt/gp/stats.h @@ -129,6 +129,68 @@ namespace blt::gp std::atomic_uint64_t deallocated_bytes = 0; }; + class call_tracker_t + { + public: + struct call_data_t + { + blt::u64 start_calls = 0; + blt::u64 start_value = 0; + blt::u64 end_calls = 0; + blt::u64 end_value = 0; + + [[nodiscard]] inline auto get_call_difference() const + { + return end_calls - start_calls; + } + + [[nodiscard]] inline auto get_value_difference() const + { + return end_value - start_value; + } + }; + + void value(blt::u64 value) + { + secondary_value += value; + } + + void call() + { + primary_calls++; + } + + void call(blt::u64 v) + { + primary_calls++; + value(v); + } + + [[nodiscard]] auto get_calls() const + { + return primary_calls.load(); + } + + [[nodiscard]] auto get_value() const + { + return secondary_value.load(); + } + + call_data_t start_measurement() + { + return {primary_calls.load(), 0}; + } + + void stop_measurement(call_data_t& data) + { + data.end_calls = primary_calls.load(); + } + + private: + std::atomic_uint64_t primary_calls = 0; + std::atomic_uint64_t secondary_value = 0; + }; + } #endif //BLT_GP_STATS_H