track peak allocations
parent
55f5b5bc05
commit
433002bb8c
|
@ -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)
|
||||||
|
|
|
@ -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%%",
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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++;
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue