diff --git a/CMakeLists.txt b/CMakeLists.txt index 6e0a494..3843b6f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.25) -project(blt-gp VERSION 0.1.21) +project(blt-gp VERSION 0.1.22) include(CTest) @@ -9,6 +9,7 @@ option(ENABLE_TSAN "Enable the thread data race sanitizer" OFF) option(BUILD_EXAMPLES "Build example programs. This will build with CTest" OFF) option(BUILD_GP_TESTS "Build test programs." OFF) option(DEBUG_LEVEL "Enable debug features which prints extra information to the console, might slow processing down. [0, 3)" 0) +option(TRACK_ALLOCATIONS "Track total allocations. Can be accessed with blt::gp::tracker" ON) set(CMAKE_CXX_STANDARD 17) @@ -38,6 +39,10 @@ target_include_directories(blt-gp PUBLIC include/) target_link_libraries(blt-gp PRIVATE BLT Threads::Threads) target_compile_definitions(blt-gp PRIVATE BLT_DEBUG_LEVEL=${DEBUG_LEVEL}) +if (${TRACK_ALLOCATIONS}) + target_compile_definitions(blt-gp PRIVATE BLT_TRACK_ALLOCATIONS=1) +endif () + if (${ENABLE_ADDRSAN} MATCHES ON) target_compile_options(blt-gp PRIVATE -fsanitize=address) target_link_options(blt-gp PRIVATE -fsanitize=address) @@ -67,6 +72,10 @@ macro(blt_add_project name source type) target_link_options(${name}-${type} PRIVATE -Wall -Wextra -Wpedantic -Wno-comment) target_compile_definitions(${name}-${type} PRIVATE BLT_DEBUG_LEVEL=${DEBUG_LEVEL}) + if (${TRACK_ALLOCATIONS}) + target_compile_definitions(${name}-${type} PRIVATE BLT_TRACK_ALLOCATIONS=1) + endif () + if (${ENABLE_ADDRSAN} MATCHES ON) target_compile_options(${name}-${type} PRIVATE -fsanitize=address) target_link_options(${name}-${type} PRIVATE -fsanitize=address) diff --git a/examples/symbolic_regression.cpp b/examples/symbolic_regression.cpp index 4db050b..3f2d7c3 100644 --- a/examples/symbolic_regression.cpp +++ b/examples/symbolic_regression.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include //static constexpr long SEED = 41912; @@ -114,15 +115,35 @@ 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; } @@ -148,7 +169,7 @@ int main() // TODO: make stats helper BLT_PRINT_PROFILE("Symbolic Regression", blt::PRINT_CYCLES | blt::PRINT_THREAD | blt::PRINT_WALL); - + // BLT_TRACE("Allocations:"); // auto h = static_cast(blt::gp::hello.load()); // auto u = static_cast(blt::gp::unhello.load()); diff --git a/include/blt/gp/stack.h b/include/blt/gp/stack.h index 71a10a7..f16590d 100644 --- a/include/blt/gp/stack.h +++ b/include/blt/gp/stack.h @@ -43,30 +43,131 @@ namespace blt::gp BLT_META_MAKE_FUNCTION_CHECK(drop); } -// inline std::atomic_uint64_t hello = 0; -// inline std::atomic_uint64_t hello_bytes = 0; -// inline std::atomic_uint64_t unhello = 0; + class allocation_tracker_t + { + public: + struct allocation_data_t + { + blt::u64 start_allocations = 0; + blt::u64 start_deallocations = 0; + blt::u64 start_allocated_bytes = 0; + blt::u64 start_deallocated_bytes = 0; + + blt::u64 end_allocations = 0; + blt::u64 end_deallocations = 0; + blt::u64 end_allocated_bytes = 0; + blt::u64 end_deallocated_bytes = 0; + + [[nodiscard]] blt::u64 getAllocationDifference() const + { + return end_allocations - start_allocations; + } + + [[nodiscard]] blt::u64 getDeallocationDifference() const + { + return end_deallocations - start_deallocations; + } + + [[nodiscard]] blt::u64 getAllocatedByteDifference() const + { + return end_allocated_bytes - start_allocated_bytes; + } + + [[nodiscard]] blt::u64 getDeallocatedByteDifference() const + { + return end_deallocated_bytes - start_deallocated_bytes; + } + }; + + void allocate(blt::size_t bytes) + { + allocations++; + allocated_bytes += bytes; + } + + void deallocate(blt::size_t bytes) + { + deallocations++; + deallocated_bytes += bytes; + } + + [[nodiscard]] blt::u64 getAllocations() const + { + return allocations; + } + + [[nodiscard]] blt::u64 getDeallocations() const + { + return deallocations; + } + + [[nodiscard]] blt::u64 getAllocatedBytes() const + { + return allocated_bytes; + } + + [[nodiscard]] blt::u64 getDeallocatedBytes() const + { + return deallocated_bytes; + } + + [[nodiscard]] blt::u64 getAllocationDifference() const + { + return std::abs(static_cast(getAllocations()) - static_cast(getDeallocations())); + } + + [[nodiscard]] blt::u64 getCurrentlyAllocatedBytes() const + { + return getAllocatedBytes() - getDeallocatedBytes(); + } + + allocation_data_t start_measurement() + { + allocation_data_t data{}; + data.start_allocations = allocations; + data.start_deallocations = deallocations; + data.start_allocated_bytes = allocated_bytes; + data.start_deallocated_bytes = deallocated_bytes; + return data; + } + + void stop_measurement(allocation_data_t& data) + { + data.end_allocations = allocations; + data.end_deallocations = deallocations; + data.end_allocated_bytes = allocated_bytes; + data.end_deallocated_bytes = deallocated_bytes; + } + + private: + std::atomic_uint64_t allocations = 0; + std::atomic_uint64_t deallocations = 0; + std::atomic_uint64_t allocated_bytes = 0; + std::atomic_uint64_t deallocated_bytes = 0; + }; + + inline allocation_tracker_t tracker; class aligned_allocator { public: void* allocate(blt::size_t bytes) // NOLINT { -// hello.fetch_add(1, std::memory_order_relaxed); -// hello_bytes += bytes; -// BLT_TRACE("Allocating %ld bytes", bytes); +#ifdef BLT_TRACK_ALLOCATIONS + tracker.allocate(bytes); +#endif return std::aligned_alloc(8, bytes); } - void deallocate(void* ptr, blt::size_t) // NOLINT + void deallocate(void* ptr, blt::size_t bytes) // NOLINT { -// if (ptr == nullptr && bytes != 0) { -// BLT_ABORT(("Nullptr called with non zero bytes! " + std::to_string(bytes)).c_str()); -// } -// if (ptr == nullptr) -// return; -// unhello.fetch_add(1, std::memory_order_relaxed); -// BLT_TRACE("Deallocating %ld bytes", bytes); + if (ptr == nullptr) + return; +#ifdef BLT_TRACK_ALLOCATIONS + tracker.deallocate(bytes); +#else + (void) bytes; +#endif std::free(ptr); } }; diff --git a/lib/blt b/lib/blt index 9ce6c89..1b09483 160000 --- a/lib/blt +++ b/lib/blt @@ -1 +1 @@ -Subproject commit 9ce6c89ce0145902d31515194a707a9aca948121 +Subproject commit 1b09483af06bab0e73fa6f0c1ab2a4ed8134ca9d