From 20e41f34ccc87cb39a4268da99df862184e3c503 Mon Sep 17 00:00:00 2001 From: Brett Date: Wed, 4 Sep 2024 02:42:31 -0400 Subject: [PATCH 1/5] trying huge pages --- CMakeLists.txt | 2 +- include/blt/gp/fwdecl.h | 146 ++++++++++++++++++++++++++++++++++++++++ include/blt/gp/stack.h | 2 +- src/program.cpp | 2 +- 4 files changed, 149 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 60783e5..e3e9fe7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.25) -project(blt-gp VERSION 0.1.45) +project(blt-gp VERSION 0.1.46) include(CTest) diff --git a/include/blt/gp/fwdecl.h b/include/blt/gp/fwdecl.h index 0a42f5c..4d7afa3 100644 --- a/include/blt/gp/fwdecl.h +++ b/include/blt/gp/fwdecl.h @@ -25,6 +25,9 @@ #include #include #include +#include +#include +#include namespace blt::gp { @@ -113,6 +116,149 @@ namespace blt::gp } }; + template + class variable_bump_allocator + { + public: + explicit variable_bump_allocator(blt::size_t default_block_size = BLT_2MB_SIZE): default_block_size(default_block_size) + {} + + void* allocate(blt::size_t bytes) + { +#ifdef BLT_TRACK_ALLOCATIONS + tracker.allocate(bytes); +#endif + std::scoped_lock lock(mutex); + if (head == nullptr || head->remaining_bytes_in_block() < static_cast(bytes)) + { + push_block(bytes); + } + auto ptr = head->metadata.offset; + head->metadata.offset += bytes; + ++head->metadata.allocated_objects; + return ptr; + } + + void deallocate(void* ptr, blt::size_t bytes) + { + if (ptr == nullptr) + return; +#ifdef BLT_TRACK_ALLOCATIONS + tracker.deallocate(bytes); +#else + (void) bytes; +#endif + std::scoped_lock lock(mutex); + auto blk = to_block(ptr); + --blk->metadata.allocated_objects; + if (blk->metadata.allocated_objects == 0) + { + if (head == blk) + head = head->metadata.next; + else + { + auto prev = head; + auto next = head->metadata.next; + while (next != blk) + { + prev = next; + next = next->metadata.next; + } + prev->metadata.next = next->metadata.next; + } + deallocated_blocks.push_back(blk); + } + } + + ~variable_bump_allocator() + { + std::scoped_lock lock(mutex); + for (auto* blk : deallocated_blocks) + alloc.deallocate(blk, blk->metadata.size); + auto cur = head; + while (cur != nullptr) + { + auto* ptr = cur; + cur = cur->metadata.next; + alloc.deallocate(ptr, ptr->metadata.size); + } + head = nullptr; + } + + private: + struct block_t + { + struct block_metadata_t + { + blt::size_t size = 0; + blt::size_t allocated_objects = 0; + block_t* next = nullptr; + blt::u8* offset = nullptr; + } metadata; + blt::u8 buffer[8]{}; + + explicit block_t(blt::size_t size) + { + metadata.size = size; + reset(); + } + + void reset() + { + metadata.offset = buffer; + } + + [[nodiscard]] blt::ptrdiff_t storage_size() const noexcept + { + return static_cast(metadata.size - sizeof(typename block_t::block_metadata_t)); + } + + [[nodiscard]] blt::ptrdiff_t used_bytes_in_block() const noexcept + { + return static_cast(metadata.offset - buffer); + } + + [[nodiscard]] blt::ptrdiff_t remaining_bytes_in_block() const noexcept + { + return storage_size() - used_bytes_in_block(); + } + }; + + static inline block_t* to_block(void* p) + { + return reinterpret_cast(reinterpret_cast(p) & static_cast(~(BLT_2MB_SIZE - 1))); + } + + void push_block(blt::size_t bytes) + { + auto blk = allocate_block(bytes); + blk->metadata.next = head; + head = blk; + } + + inline block_t* allocate_block(blt::size_t bytes) + { + if (!deallocated_blocks.empty()) + { + auto blk = deallocated_blocks.back(); + blk->reset(); + deallocated_blocks.pop_back(); + return blk; + } + auto size = align_size_to(bytes + sizeof(typename block_t::block_metadata_t), default_block_size); + auto* ptr = static_cast(alloc.allocate(size, blt::huge_page_t::BLT_2MB_PAGE)); + new(ptr) block_t{size}; + return ptr; + } + + private: + block_t* head = nullptr; + std::mutex mutex; + std::vector deallocated_blocks; + Alloc alloc; + blt::size_t default_block_size; + }; + template class tracked_allocator_t { diff --git a/include/blt/gp/stack.h b/include/blt/gp/stack.h index 4a883ab..19e8489 100644 --- a/include/blt/gp/stack.h +++ b/include/blt/gp/stack.h @@ -49,7 +49,7 @@ namespace blt::gp constexpr static blt::size_t MAX_ALIGNMENT = 8; template using NO_REF_T = std::remove_cv_t>; - using Allocator = aligned_allocator; + using Allocator = variable_bump_allocator<>; public: static Allocator& get_allocator(); diff --git a/src/program.cpp b/src/program.cpp index 8481451..07f8467 100644 --- a/src/program.cpp +++ b/src/program.cpp @@ -52,7 +52,7 @@ namespace blt::gp stack_allocator::Allocator& stack_allocator::get_allocator() { - thread_local static Allocator allocator; + static Allocator allocator; return allocator; } From d40f741431af52c2ce23c4e7c42b24fe63c8df2a Mon Sep 17 00:00:00 2001 From: Brett Date: Wed, 4 Sep 2024 13:30:05 -0400 Subject: [PATCH 2/5] fix the stupid segfault using an ugly hack. TODO: make allocator owned by classes (silly) --- CMakeLists.txt | 2 +- examples/symbolic_regression.cpp | 10 +++++++ include/blt/gp/fwdecl.h | 50 +++++++++++++++++++------------- lib/blt | 2 +- 4 files changed, 42 insertions(+), 22 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e3e9fe7..2a27092 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.25) -project(blt-gp VERSION 0.1.46) +project(blt-gp VERSION 0.1.47) include(CTest) diff --git a/examples/symbolic_regression.cpp b/examples/symbolic_regression.cpp index 45b44a3..b51b6e4 100644 --- a/examples/symbolic_regression.cpp +++ b/examples/symbolic_regression.cpp @@ -44,6 +44,16 @@ blt::gp::prog_config_t config = blt::gp::prog_config_t() .set_max_generations(50) .set_pop_size(20000) .set_thread_count(0); +//blt::gp::prog_config_t config = blt::gp::prog_config_t() +// .set_initial_min_tree_size(2) +// .set_initial_max_tree_size(6) +// .set_elite_count(2) +// .set_crossover_chance(0.9) +// .set_mutation_chance(0.1) +// .set_reproduction_chance(0) +// .set_max_generations(50) +// .set_pop_size(500) +// .set_thread_count(0); blt::gp::gp_program program{SEED, config}; diff --git a/include/blt/gp/fwdecl.h b/include/blt/gp/fwdecl.h index 4d7afa3..c824622 100644 --- a/include/blt/gp/fwdecl.h +++ b/include/blt/gp/fwdecl.h @@ -149,24 +149,29 @@ namespace blt::gp (void) bytes; #endif std::scoped_lock lock(mutex); - auto blk = to_block(ptr); + block_t* blk = to_block(ptr); --blk->metadata.allocated_objects; if (blk->metadata.allocated_objects == 0) { - if (head == blk) - head = head->metadata.next; + if (blk->metadata.has_deallocated) + alloc.deallocate(blk, blk->metadata.size); else { - auto prev = head; - auto next = head->metadata.next; - while (next != blk) + if (head == blk) + head = head->metadata.next; + else { - prev = next; - next = next->metadata.next; + auto prev = head; + auto next = head->metadata.next; + while (next != blk) + { + prev = next; + next = next->metadata.next; + } + prev->metadata.next = next->metadata.next; } - prev->metadata.next = next->metadata.next; + deallocated_blocks.push_back(blk); } - deallocated_blocks.push_back(blk); } } @@ -174,13 +179,15 @@ namespace blt::gp { std::scoped_lock lock(mutex); for (auto* blk : deallocated_blocks) + { alloc.deallocate(blk, blk->metadata.size); + } auto cur = head; while (cur != nullptr) { auto* ptr = cur; + ptr->metadata.has_deallocated = true; cur = cur->metadata.next; - alloc.deallocate(ptr, ptr->metadata.size); } head = nullptr; } @@ -190,22 +197,24 @@ namespace blt::gp { struct block_metadata_t { - blt::size_t size = 0; - blt::size_t allocated_objects = 0; - block_t* next = nullptr; - blt::u8* offset = nullptr; + blt::size_t size; + blt::size_t allocated_objects : 63; + bool has_deallocated : 1; + block_t* next; + blt::u8* offset; } metadata; blt::u8 buffer[8]{}; - explicit block_t(blt::size_t size) + explicit block_t(blt::size_t size): metadata{size, 0, false, nullptr, nullptr} { - metadata.size = size; reset(); } void reset() { metadata.offset = buffer; + metadata.allocated_objects = 0; + metadata.next = nullptr; } [[nodiscard]] blt::ptrdiff_t storage_size() const noexcept @@ -232,6 +241,7 @@ namespace blt::gp void push_block(blt::size_t bytes) { auto blk = allocate_block(bytes); + BLT_TRACE("Allocated block %p", blk); blk->metadata.next = head; head = blk; } @@ -240,9 +250,9 @@ namespace blt::gp { if (!deallocated_blocks.empty()) { - auto blk = deallocated_blocks.back(); - blk->reset(); + block_t* blk = deallocated_blocks.back(); deallocated_blocks.pop_back(); + blk->reset(); return blk; } auto size = align_size_to(bytes + sizeof(typename block_t::block_metadata_t), default_block_size); @@ -255,8 +265,8 @@ namespace blt::gp block_t* head = nullptr; std::mutex mutex; std::vector deallocated_blocks; - Alloc alloc; blt::size_t default_block_size; + Alloc alloc; }; template diff --git a/lib/blt b/lib/blt index a7645d9..82cc1af 160000 --- a/lib/blt +++ b/lib/blt @@ -1 +1 @@ -Subproject commit a7645d9ddec57ecaad525b48a30f8001adcf75e8 +Subproject commit 82cc1aff9688e1917e261bd341178562f37e190a From a19712a4d7e7e42e5475459fa08afd4b8577dd89 Mon Sep 17 00:00:00 2001 From: Brett Laptop Date: Wed, 4 Sep 2024 16:05:35 -0400 Subject: [PATCH 3/5] fetch allocator --- CMakeLists.txt | 2 +- include/blt/gp/fwdecl.h | 4 ++-- lib/blt | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2a27092..bbb9149 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.25) -project(blt-gp VERSION 0.1.47) +project(blt-gp VERSION 0.1.48) include(CTest) diff --git a/include/blt/gp/fwdecl.h b/include/blt/gp/fwdecl.h index c824622..20c71fa 100644 --- a/include/blt/gp/fwdecl.h +++ b/include/blt/gp/fwdecl.h @@ -116,7 +116,7 @@ namespace blt::gp } }; - template + template class variable_bump_allocator { public: @@ -256,7 +256,7 @@ namespace blt::gp return blk; } auto size = align_size_to(bytes + sizeof(typename block_t::block_metadata_t), default_block_size); - auto* ptr = static_cast(alloc.allocate(size, blt::huge_page_t::BLT_2MB_PAGE)); + auto* ptr = static_cast(alloc.allocate(size)); new(ptr) block_t{size}; return ptr; } diff --git a/lib/blt b/lib/blt index 82cc1af..7198a8b 160000 --- a/lib/blt +++ b/lib/blt @@ -1 +1 @@ -Subproject commit 82cc1aff9688e1917e261bd341178562f37e190a +Subproject commit 7198a8b0c32e35c9d80d8e44ff17c7199ddde6f8 From be87d291287f283b5a63878385c4098618d87bc3 Mon Sep 17 00:00:00 2001 From: Brett Laptop Date: Wed, 4 Sep 2024 16:16:56 -0400 Subject: [PATCH 4/5] get rid of alloc message --- CMakeLists.txt | 2 +- include/blt/gp/fwdecl.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bbb9149..31606b0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.25) -project(blt-gp VERSION 0.1.48) +project(blt-gp VERSION 0.1.49) include(CTest) diff --git a/include/blt/gp/fwdecl.h b/include/blt/gp/fwdecl.h index 20c71fa..1a75b90 100644 --- a/include/blt/gp/fwdecl.h +++ b/include/blt/gp/fwdecl.h @@ -241,7 +241,7 @@ namespace blt::gp void push_block(blt::size_t bytes) { auto blk = allocate_block(bytes); - BLT_TRACE("Allocated block %p", blk); +// BLT_TRACE("Allocated block %p", blk); blk->metadata.next = head; head = blk; } From a1b43bee51ab138ee39aebdcc338de4545867833 Mon Sep 17 00:00:00 2001 From: Brett Date: Wed, 4 Sep 2024 21:21:04 -0400 Subject: [PATCH 5/5] revert changes? --- CMakeLists.txt | 2 +- include/blt/gp/program.h | 1 - include/blt/gp/stack.h | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 31606b0..d8de23b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.25) -project(blt-gp VERSION 0.1.49) +project(blt-gp VERSION 0.1.50) include(CTest) diff --git a/include/blt/gp/program.h b/include/blt/gp/program.h index ad2af8c..fca001d 100644 --- a/include/blt/gp/program.h +++ b/include/blt/gp/program.h @@ -128,7 +128,6 @@ namespace blt::gp // largest = largest * largest_argc; blt::size_t largest = largest_args * largest_argc * largest_returns * largest_argc; - BLT_TRACE(largest); storage.eval_func = [&operators..., largest](const tree_t& tree, void* context) -> evaluation_context& { const auto& ops = tree.get_operations(); diff --git a/include/blt/gp/stack.h b/include/blt/gp/stack.h index 19e8489..4a883ab 100644 --- a/include/blt/gp/stack.h +++ b/include/blt/gp/stack.h @@ -49,7 +49,7 @@ namespace blt::gp constexpr static blt::size_t MAX_ALIGNMENT = 8; template using NO_REF_T = std::remove_cv_t>; - using Allocator = variable_bump_allocator<>; + using Allocator = aligned_allocator; public: static Allocator& get_allocator();