Skip to content

Add support for custom allocators across Morpheus core components #465

@Twon

Description

@Twon

Summary

Introduce support for user-provided/custom allocators throughout the Morpheus codebase to enable greater control over memory management, performance tuning, and integration with specialised runtime environments.

Motivation

Morpheus is increasingly being used in performance-critical and resource-constrained environments (e.g. low-latency systems, high-throughput pipelines, and custom runtime contexts). In such domains, the ability to control memory allocation strategies is essential.

Currently, Morpheus relies on default allocation mechanisms (e.g. new, std::allocator), which imposes several limitations:

  • Lack of control over allocation strategy
    Users cannot plug in arena allocators, pool allocators, or monotonic buffers to reduce allocation overhead or fragmentation.

  • Performance constraints
    High-frequency allocations in hot paths (e.g. parsing, transformations, container usage) may introduce unnecessary latency and cache inefficiencies.

  • Integration limitations
    Many systems (game engines, trading systems, embedded platforms) require allocations to go through custom memory subsystems for tracking, alignment, or safety guarantees.

  • Testing and instrumentation
    Custom allocators enable better observability (allocation tracking, leak detection, failure injection), which is currently difficult to achieve.

Proposal

Introduce allocator-awareness across relevant Morpheus components, following established C++ practices:

1. Allocator-aware types

  • Update core containers and data structures to accept an allocator template parameter where appropriate.

  • Follow the standard library model:

    template <typename T, typename Allocator = std::allocator<T>>
    class container;

2. Propagation and consistency

  • Ensure allocators propagate correctly through:

    • Copy/move construction
    • Assignment
    • Nested/container members
  • Align with std::allocator_traits semantics.

3. PMR support (optional but recommended)

  • Consider providing support for std::pmr:

    • std::pmr::polymorphic_allocator
    • std::pmr::memory_resource
  • This allows runtime-configurable allocation strategies without templating explosion.

4. Default behaviour remains unchanged

  • Preserve current behaviour by default:

    • If no allocator is provided, continue using std::allocator.
  • Ensure zero-cost abstraction where possible.

Design Considerations

  • Header/module boundaries
    Care must be taken to ensure allocator types are correctly exported across module interfaces.

  • ABI impact
    Introducing allocator template parameters may affect ABI stability; changes should be scoped to avoid breaking consumers where possible.

  • Complexity vs benefit
    Allocator support should be introduced incrementally, prioritising:

    • Frequently used containers
    • Performance-critical paths
  • Monadic/functional components
    For parts of Morpheus using monadic patterns, ensure allocator usage does not overly complicate value semantics or chaining.

Alternatives Considered

  • Global allocator hooks
    Rejected due to lack of composability and poor isolation between components.

  • Hardcoded custom allocators
    Too restrictive; does not allow users to integrate their own memory strategies.

Benefits

  • Improved performance in allocation-heavy workloads
  • Better integration with specialised systems
  • Enhanced testing and debugging capabilities
  • Greater flexibility for library users without impacting default usability

Potential Next Steps

  1. Identify core types that would benefit most from allocator support
  2. Prototype allocator-aware container(s)
  3. Evaluate PMR integration
  4. Document allocator usage patterns for users

Open Questions

  • Should PMR be the primary abstraction, or an optional layer?
  • Which components should be prioritised for initial support?
  • Do we need allocator-aware APIs, or just allocator-aware types?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions