-
Notifications
You must be signed in to change notification settings - Fork 37
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
Implement more robust memory pool lookup (#243) #335
base: main
Are you sure you want to change the base?
Conversation
let pool_ind = self | ||
// This finds a (not necessarily first) pool that matches the size exactly | ||
// or returns error with index where a matching element could be inserted while maintaining sorted order | ||
.binary_search_by_key(&size, |p| p.max_alloc_size()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
size
won't be equal to any of the max_alloc_sizes
, we should find a bucket where size >= min_slice_size && size <= max_alloc_size
. We don't need binary search since we only have < 10 buckets, max 20. Having the trait is great though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I didn't know about the size >= min_slice_size
condition. But I also can't find min_slice_size
defined anywhere.
Is the Vec<DynamicPools>
sorted by min_slice_size
too? Because then binary search would still be possible.
Binary search was what partition_point()
was doing and this implementation only extends that technique. But with such a small array size I do agree that linear search will not impact the performance and will allow for the size >= min_slice_size
condition - I'll change the implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hiya - give I wrote this I'll barge in - there is no min_slice_size, that's implicit by the fact that that should have been allocated in the previous pool. Stuff being sorted is therefore a condition anyway - and binary search seems fine? I agree it's a small performance win but... idk, seems clearer & faster. I just didn't quite handle the error condition of the search correctly.
The trait also seems like it could just be a struct? Doubt you'd want multiple possible implementations of this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In case there's only one condition, then the most important consideration for using binary search is that if there are two pools with same max_alloc_size
then it's not predictable which one will be chosen. The question is if that's an acceptable behaviour.
The trait also seems like it could just be a struct? Doubt you'd want multiple possible implementations of this.
Struct or newtype would require changing the type of pools
in MemoryManagement
and I didn't feel comfortable doing that. So I created the trait, which I admit is a little bit excessive, but necessary for borrow checker.
Fixes #243
I have implemented a more robust way to find big enough memory pool for reserve/alloc. I think comments explain quite well what happens in the code.
Minimal example of the solution
I have also added a simple test to check if the code panics when too much memory is requested.
To avoid code repetition in
reserve()
andalloc()
I've extracted the solution into a separate function. But becausealloc
andreserve
require&mut Storage
the finder function needs to be implemented for directly forpools
(to have two mutable borrows for pools and storage). But asVec<DynamicPool>
is a foreign type I had to implement the function via trait, hence the addition ofPoolFind
trait.I hope this PR helps you. If something needs improvements or corrections, please let me know.