Skip to content

Feature: More accurate memory statistics #608

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
3 tasks done
mapleFU opened this issue May 16, 2025 · 3 comments
Open
3 tasks done

Feature: More accurate memory statistics #608

mapleFU opened this issue May 16, 2025 · 3 comments
Labels
enhancement New feature or request

Comments

@mapleFU
Copy link
Contributor

mapleFU commented May 16, 2025

Describe what you are looking for

In memory_mapping_allocator_gt, memory is allocated in last_arena_, the scaling code is listed below:

std::size_t new_cap = (std::max)(last_capacity_, ceil2(extended_bytes)) * capacity_multiplier();

And memory used is not stored in allocator, instead it's calculated:

std::size_t total_allocated() const noexcept {
if (!last_arena_)
return 0;
std::size_t total_used = 0;
std::size_t last_capacity = last_capacity_;
do {
total_used += last_capacity;
last_capacity /= capacity_multiplier();
} while (last_capacity >= min_capacity());
return total_used;

Since memory scaling is not simply * 2

Can you contribute to the implementation?

  • I can contribute

Is your feature request specific to a certain interface?

It applies to everything

Contact Details

[email protected]

Is there an existing issue for this?

  • I have searched the existing issues

Code of Conduct

  • I agree to follow this project's Code of Conduct
@mapleFU mapleFU added the enhancement New feature or request label May 16, 2025
@mapleFU
Copy link
Contributor Author

mapleFU commented May 16, 2025

Strategy one: add a variable

diff --git a/include/usearch/index_plugins.hpp b/include/usearch/index_plugins.hpp
index e13703d..2318b0b 100644
--- a/include/usearch/index_plugins.hpp
+++ b/include/usearch/index_plugins.hpp
@@ -889,6 +889,7 @@ template <std::size_t alignment_ak = 1> class memory_mapping_allocator_gt {
     std::size_t last_usage_ = head_size();
     std::size_t last_capacity_ = min_capacity();
     std::size_t wasted_space_ = 0;
+    std::size_t total_allocated_ = 0; // Track total allocated memory
 
   public:
     using value_type = byte_t;
@@ -899,13 +900,15 @@ template <std::size_t alignment_ak = 1> class memory_mapping_allocator_gt {
     memory_mapping_allocator_gt() = default;
     memory_mapping_allocator_gt(memory_mapping_allocator_gt&& other) noexcept
         : last_arena_(exchange(other.last_arena_, nullptr)), last_usage_(exchange(other.last_usage_, 0)),
-          last_capacity_(exchange(other.last_capacity_, 0)), wasted_space_(exchange(other.wasted_space_, 0)) {}
+          last_capacity_(exchange(other.last_capacity_, 0)), wasted_space_(exchange(other.wasted_space_, 0)),
+          total_allocated_(exchange(other.total_allocated_, 0)) {}
 
     memory_mapping_allocator_gt& operator=(memory_mapping_allocator_gt&& other) noexcept {
         std::swap(last_arena_, other.last_arena_);
         std::swap(last_usage_, other.last_usage_);
         std::swap(last_capacity_, other.last_capacity_);
         std::swap(wasted_space_, other.wasted_space_);
+        std::swap(total_allocated_, other.total_allocated_);
         return *this;
     }
 
@@ -930,6 +933,7 @@ template <std::size_t alignment_ak = 1> class memory_mapping_allocator_gt {
         last_usage_ = head_size();
         last_capacity_ = min_capacity();
         wasted_space_ = 0;
+        total_allocated_ = 0;
     }
 
     /**
@@ -968,6 +972,7 @@ template <std::size_t alignment_ak = 1> class memory_mapping_allocator_gt {
             last_arena_ = new_arena;
             last_capacity_ = new_cap;
             last_usage_ = head_size();
+            total_allocated_ += new_cap;
         }
 
         wasted_space_ += extended_bytes - count_bytes;
@@ -979,15 +984,7 @@ template <std::size_t alignment_ak = 1> class memory_mapping_allocator_gt {
      *  @return The amount of space in bytes.
      */
     std::size_t total_allocated() const noexcept {
-        if (!last_arena_)
-            return 0;
-        std::size_t total_used = 0;
-        std::size_t last_capacity = last_capacity_;
-        do {
-            total_used += last_capacity;
-            last_capacity /= capacity_multiplier();
-        } while (last_capacity >= min_capacity());
-        return total_used;
+        return total_allocated_; // Return tracked total allocated memory
     }

@mapleFU
Copy link
Contributor Author

mapleFU commented May 16, 2025

Another method:

    /**
     *  @brief Returns the amount of memory used by the allocator across all arenas.
     *  @return The amount of space in bytes.
     */
    std::size_t total_allocated() const noexcept {
        if (!last_arena_)
            return 0;
            
        std::size_t total_used = 0;
        byte_t* current_arena = last_arena_;
        
        while (current_arena) {
            std::size_t current_cap = 0;
            std::memcpy(&current_cap, current_arena + sizeof(byte_t*), sizeof(std::size_t));
            total_used += current_cap;
            
            byte_t* previous_arena = nullptr;
            std::memcpy(&previous_arena, current_arena, sizeof(byte_t*));
            current_arena = previous_arena;
        }
        
        return total_used;
    }

@mapleFU
Copy link
Contributor Author

mapleFU commented May 16, 2025

@ashvardanian would you mind take a look?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant