diff --git a/CMakeLists.txt b/CMakeLists.txt index fbd2149..e50bade 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.25) -project(blt-gp VERSION 0.0.76) +project(blt-gp VERSION 0.0.77) include(CTest) diff --git a/examples/pg_symbolic_regression.cpp b/examples/pg_symbolic_regression.cpp index 21618ca..0dbcf00 100644 --- a/examples/pg_symbolic_regression.cpp +++ b/examples/pg_symbolic_regression.cpp @@ -36,7 +36,7 @@ blt::gp::prog_config_t config = blt::gp::prog_config_t() .set_initial_max_tree_size(6) .set_elite_count(0) .set_max_generations(50) - .set_pop_size(5000) + .set_pop_size(500) .set_thread_count(0); blt::gp::type_provider type_system; diff --git a/include/blt/gp/stack.h b/include/blt/gp/stack.h index 43cd334..e7bd161 100644 --- a/include/blt/gp/stack.h +++ b/include/blt/gp/stack.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -32,6 +33,110 @@ namespace blt::gp { + class huge_allocator + { + public: + constexpr static blt::size_t HUGE_PAGE_SIZE = BLT_2MB_SIZE; + static_assert(((HUGE_PAGE_SIZE & (HUGE_PAGE_SIZE - 1)) == 0) && "Must be a power of two!"); + + void* allocate(blt::size_t bytes) + { + std::scoped_lock lock(mutex); + if (bytes > HUGE_PAGE_SIZE) + throw std::runtime_error("Unable to allocate more than 2mb of space at a time!"); + if (head == nullptr || head.load()->remaining_bytes() < bytes) + push_block(); + auto ptr = head.load()->metadata.offset; + head.load()->metadata.offset += bytes; + head.load()->metadata.allocated_objects++; + return ptr; + } + + void deallocate(void* ptr) + { + std::scoped_lock lock(mutex); + auto block = to_block(ptr); + block->metadata.allocated_objects--; + if (block->metadata.allocated_objects == 0) + delete_block(block); + } + + private: + struct block + { + struct block_metadata_t + { + blt::ptrdiff_t allocated_objects = 0; + block* next = nullptr; + block* prev = nullptr; + blt::u8* offset = nullptr; + } metadata; + blt::u8 buffer[HUGE_PAGE_SIZE - sizeof(block_metadata_t)]{}; + + block() + { + metadata.offset = buffer; + } + + void reset() + { + metadata.allocated_objects = 0; + metadata.offset = buffer; + metadata.next = nullptr; + metadata.prev = nullptr; + } + + blt::size_t remaining_bytes() + { + static constexpr blt::size_t BLOCK_REMAINDER = HUGE_PAGE_SIZE - sizeof(block_metadata_t); + return BLOCK_REMAINDER - static_cast(metadata.offset - buffer); + } + }; + + template + static inline block* to_block(T* p) + { + return reinterpret_cast(reinterpret_cast(p) & static_cast(~(HUGE_PAGE_SIZE - 1))); + } + + void delete_block(block* b) + { + if (b->metadata.prev != nullptr) + b->metadata.prev->metadata.next = b->metadata.next; + deallocated_blocks.push_back(b); + } + + void push_block() + { + block * block; + if (deallocated_blocks.empty()) + block = allocate_block(); + else + { + block = deallocated_blocks.back(); + deallocated_blocks.pop_back(); + block->reset(); + } + block->metadata.prev = head; + if (head != nullptr) + head.load()->metadata.next = block; + head = block; + } + + static block* allocate_block() + { + auto* buffer = reinterpret_cast(std::aligned_alloc(HUGE_PAGE_SIZE, HUGE_PAGE_SIZE)); + new(buffer) block{}; + return buffer; + } + + std::atomic head = nullptr; + std::mutex mutex; + std::vector deallocated_blocks; + }; + + huge_allocator& get_allocator(); + class stack_allocator { constexpr static blt::size_t PAGE_SIZE = 0x1000; @@ -380,6 +485,7 @@ namespace blt::gp { auto size = to_nearest_page_size(bytes); auto* data = std::aligned_alloc(PAGE_SIZE, size); + //auto* data = get_allocator().allocate(size); new(data) block{size}; return reinterpret_cast(data); } @@ -391,6 +497,7 @@ namespace blt::gp block* ptr = current; current = current->metadata.prev; std::free(ptr); + //get_allocator().deallocate(ptr); } } @@ -403,7 +510,7 @@ namespace blt::gp head = old; head->reset(); } - //free_chain(old); + //free_chain(old); // required to prevent silly memory :3 // if (head != nullptr) // head->metadata.next = nullptr; diff --git a/lib/blt b/lib/blt index 9a437ec..60f7796 160000 --- a/lib/blt +++ b/lib/blt @@ -1 +1 @@ -Subproject commit 9a437ec75a41cc32e716da7d88cf36007f30f268 +Subproject commit 60f77961fbbd4a1a06adbef984d838c5b49b3718 diff --git a/src/program.cpp b/src/program.cpp index 48ba60d..fda45e6 100644 --- a/src/program.cpp +++ b/src/program.cpp @@ -73,4 +73,10 @@ namespace blt::gp })); } } + + huge_allocator& get_allocator() + { + static huge_allocator alloc; + return alloc; + } } \ No newline at end of file