#memory-allocator #real-time #gpu #allocation #hard #offset

offset-allocator

A port of Sebastian Aaltonen’s OffsetAllocator to Rust

2 unstable releases

0.2.0 Jul 9, 2024
0.1.0 May 1, 2024

#59 in Memory management

Download history 2527/week @ 2024-07-22 2621/week @ 2024-07-29 2494/week @ 2024-08-05 2795/week @ 2024-08-12 2948/week @ 2024-08-19 3099/week @ 2024-08-26 3107/week @ 2024-09-02 3837/week @ 2024-09-09 4270/week @ 2024-09-16 5812/week @ 2024-09-23 6697/week @ 2024-09-30 6179/week @ 2024-10-07 4394/week @ 2024-10-14 4242/week @ 2024-10-21 5066/week @ 2024-10-28 5763/week @ 2024-11-04

19,976 downloads per month

MIT license

37KB
650 lines

offset-allocator

Overview

This is a port of Sebastian Aaltonen's OffsetAllocator package for C++ to 100% safe Rust. It's a fast, simple, hard real time allocator. This is especially useful for managing GPU resources, and the goal is to use it in Bevy.

The port has been made into more or less idiomatic Rust but is otherwise mostly line-for-line, preserving comments. That way, patches for the original OffsetAllocator should be readily transferable to this Rust port.

Please note that offset-allocator isn't a Rust allocator conforming to the GlobalAlloc trait. You can't use this crate as a drop-in replacement for the system allocator, jemalloc, wee_alloc, etc. The general algorithm that this crate uses could be adapted to construct a Rust allocator, but that's beyond the scope of this particular implementation. This is by design, so that this allocator can be used to manage resources that aren't just CPU memory: in particular, you can manage allocations inside GPU buffers with it. By contrast, Rust allocators are hard-wired to the CPU and can't be used to manage GPU resources.

Description

This allocator is completely agnostic to what it's allocating: it only knows about a contiguous block of memory of a specific size. That size need not be in bytes: this is especially useful when allocating inside a buffer of fixed-size structures. For example, if using this allocator to divide up a GPU index buffer object, one might want to treat the units of allocation as 32-bit floats.

From the original README:

Fast hard realtime O(1) offset allocator with minimal fragmentation.

Uses 256 bins with 8 bit floating point distribution (3 bit mantissa + 5 bit exponent) and a two level bitfield to find the next available bin using 2x LZCNT instructions to make all operations O(1). Bin sizes following the floating point distribution ensures hard bounds for memory overhead percentage regarless of size class. Pow2 bins would waste up to +100% memory (+50% on average). Our float bins waste up to +12.5% (+6.25% on average).

The allocation metadata is stored in a separate data structure, making this allocator suitable for sub-allocating any resources, such as GPU heaps, buffers and arrays. Returns an offset to the first element of the allocated contiguous range.

References

Again per the original README:

This allocator is similar to the two-level segregated fit (TLSF) algorithm.

Comparison paper shows that TLSF algorithm provides best in class performance and fragmentation: https://www.researchgate.net/profile/Alfons-Crespo/publication/234785757_A_comparison_of_memory_allocators_for_real-time_applications/links/5421d8550cf2a39f4af765f4/A-comparison-of-memory-allocators-for-real-time-applications.pdf

Author

C++ version: Sebastian Aaltonen

Rust port: Patrick Walton, @pcwalton

License

Licensed under the MIT license. See LICENSE-MIT for details.

Code of conduct

offset-allocator follows the same code of conduct as Rust itself. Reports can be made to the project authors.

Dependencies

~110KB