Added SegmentedPool
This commit is contained in:
239
README.md
239
README.md
@@ -1,2 +1,237 @@
|
||||
# CSUnmangedMMU
|
||||
A C# Memory manager that provides a Segmented Memory Pool and Persistent pool
|
||||
# UnmanagedMMU
|
||||
|
||||
UnmanagedMMU is a high-performance C# memory manager library that provides efficient unmanaged memory allocation.
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [SegmentedPool](#segmentedpool)
|
||||
- [Segments](#segments)
|
||||
- [Allocation Strategy](#allocation-strategy)
|
||||
- [Constructor](#segmentedpool-constructor)
|
||||
- [Allocate](#segmentedpool-allocate)
|
||||
- [SetSegmentSize](#segmentedpool-set-segment-size)
|
||||
- [ResetSegmentSize](#segmentedpool-reset-segment-size)
|
||||
- [Reset](#segmentedpool-reset)
|
||||
- [Trim](#segmentedpool-trim)
|
||||
- [Dispose](#segmentedpool-dispose)
|
||||
|
||||
---
|
||||
|
||||
## SegmentedPool
|
||||
|
||||
A `SegmentedPool` is a **segmented bump allocator** for unmanaged memory in C#. It pre-allocates memory in **fixed-size segments** and serves allocations sequentially within each segment.
|
||||
Once a segment is full, the pool automatically switches to a new segment, allowing fast, contiguous allocations without fragmentation.
|
||||
|
||||
Advantages of the `SegmentedPool`:
|
||||
|
||||
- **High performance**: Allocation is simple pointer arithmetic.
|
||||
- **Contiguous memory**: Reduces cache misses and improves data locality.
|
||||
- **Thread-safe**: Supports concurrent allocation operations.
|
||||
- **Manual memory control**: Works outside of .NET GC, ideal for high-performance or low-latency scenarios.
|
||||
|
||||
---
|
||||
|
||||
### Segments
|
||||
|
||||
A **Segment** is a contiguous block of unmanaged memory managed by the pool. Each segment contains:
|
||||
|
||||
| Field | Type | Description |
|
||||
|-----------|-------|-------------|
|
||||
| `Ptr` | `byte*` | Pointer to the start of the unmanaged memory block. |
|
||||
| `Offset` | `nuint` | Current allocation offset within the segment. Increases as memory is allocated. |
|
||||
| `Size` | `nuint` | Total size of the segment in bytes. |
|
||||
|
||||
Segments are allocated automatically by the pool and should **never be modified outside the pool**.
|
||||
|
||||
---
|
||||
|
||||
### Allocation Strategy
|
||||
|
||||
The `SegmentedPool` uses a **bump allocator** strategy:
|
||||
|
||||
1. Memory is allocated sequentially within the current [Segments](#segments).
|
||||
2. `Offset` is incremented with each allocation.
|
||||
3. When the current segment does not have enough space, the pool switches to a new [Segments](#segments) (either from the free pool or a freshly allocated one).
|
||||
|
||||
This provides **O(1) allocation performance** for most operations.
|
||||
|
||||
---
|
||||
|
||||
### Constructor <a name="segmentedpool-constructor"></a>
|
||||
|
||||
Initializes a new instance of the SegmentedPool with the specified segment size and number of pre-allocated [Segments](#segments).
|
||||
|
||||
#### Syntax
|
||||
|
||||
```csharp
|
||||
SegmentedPool pool = new SegmentedPool(segmentSize: 4 * 1024 * 1024, initialSegments: 4);
|
||||
```
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| ----------------- | ------- | ----------------------------------------------------------------------------------- |
|
||||
| `segmentSize` | `nuint` | Size of each [Segment](#segments) in bytes. Optional. Defaults to 4 MiB (4 *1024* 1024 bytes). |
|
||||
| `initialSegments` | `int` | Number of [Segments](#segments) to pre-allocate in the pool. Optional. Defaults to 4. |
|
||||
|
||||
#### Return value
|
||||
|
||||
Returns a new instance of the SegmentedPool with the specified [Segments](#segments) size and number of pre-allocated [Segments](#segments).
|
||||
|
||||
#### Remarks
|
||||
|
||||
The SegmentedPool pre-allocates the specified number of [Segments](#segments) during construction, ensuring that the pool can immediately serve allocations without additional memory allocation overhead. The pool operates in unmanaged memory and bypasses the .NET garbage collector, so all memory must be manually released by calling Dispose() when the pool is no longer needed.
|
||||
|
||||
---
|
||||
|
||||
### Allocate <a name="segmentedpool-allocate"></a>
|
||||
|
||||
Allocates a span of unmanaged memory for elements of type T from the pool.
|
||||
|
||||
#### Syntax
|
||||
|
||||
```csharp
|
||||
Span<T> buffer = pool.Allocate<T>(count);
|
||||
```
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| ----------- | ------- | ----------------------------------------------------------------------------- |
|
||||
| `count` | `int` | Number of elements of type T to allocate. Must be greater than zero. |
|
||||
|
||||
#### Return value
|
||||
|
||||
A `Span<T>` representing the allocated memory. The span is valid until the pool is reset or disposed.
|
||||
|
||||
#### Remarks
|
||||
|
||||
Accessing the memory after calling Reset() or Dispose() is undefined behavior and may lead to crashes.
|
||||
|
||||
---
|
||||
|
||||
### SetSegmentSize <a name="segmentedpool-set-segment-size"></a>
|
||||
|
||||
Sets the [Segment](#segments) size to use for future allocations.
|
||||
|
||||
#### Syntax
|
||||
|
||||
```csharp
|
||||
pool.SetSegmentSize(newSize);
|
||||
```
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ----- | ------------------------------------------- |
|
||||
| `newSize` | nuint | The new segment size in bytes. Must be > 0. |
|
||||
|
||||
#### Return value
|
||||
|
||||
None.
|
||||
|
||||
#### Remarks
|
||||
|
||||
This method will only affect the [Segment](#segments) size of future allocations; it does not modify existing [Segments](#segments).
|
||||
|
||||
---
|
||||
|
||||
### ResetSegmentSize <a name="segmentedpool-reset-segment-size"></a>
|
||||
|
||||
Resets the [Segment](#segments) size for future allocations back to the default (4 MiB).
|
||||
|
||||
#### Syntax
|
||||
|
||||
```csharp
|
||||
pool.ResetSegmentSize();
|
||||
```
|
||||
|
||||
#### Parameters
|
||||
|
||||
None.
|
||||
|
||||
#### Return value
|
||||
|
||||
None.
|
||||
|
||||
#### Remarks
|
||||
|
||||
This method will only affect the [Segment](#segments) size of future allocations; it does not modify existing [Segments](#segments).
|
||||
|
||||
---
|
||||
|
||||
### Reset <a name="segmentedpool-reset"></a>
|
||||
|
||||
Resets the pool, returning all active [Segments](#segments) to the free pool for reuse.
|
||||
|
||||
#### Syntax
|
||||
|
||||
```csharp
|
||||
pool.Reset(trim: false);
|
||||
```
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| ----------- | ------- | ----------------------------------------------------------------------------- |
|
||||
| `trim` | `bool` | Optional. If true, trims excess free [Segments](#segments) after reset. Defaults to false |
|
||||
|
||||
#### Return value
|
||||
|
||||
None.
|
||||
|
||||
#### Remarks
|
||||
|
||||
This method resets all active [Segments](#segments)’ offsets to zero. Additionally, no memory is freed unless trim is true; the pool retains free [Segments](#segments) for future allocations.
|
||||
|
||||
---
|
||||
|
||||
### Trim <a name="segmentedpool-trim"></a>
|
||||
|
||||
Frees unused [Segments](#segments) in the free pool, reducing memory usage.
|
||||
|
||||
#### Syntax
|
||||
|
||||
```csharp
|
||||
pool.Trim(minFreeSegments: 16);
|
||||
```
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| ----------- | ------- | ----------------------------------------------------------------------------- |
|
||||
| `minFreeSegments` | `int` | Minimum number of free [Segments](#segments) to retain. [Segments](#segments) beyond this count are released. Defaults to 16. |
|
||||
|
||||
#### Return value
|
||||
|
||||
None.
|
||||
|
||||
#### Remarks
|
||||
|
||||
This method releases unmanaged memory for excess [Segments](#segments) beyond the specified minimum. This is useful for helping to controlthe unmanaged memory footprint in long-running applications.
|
||||
|
||||
---
|
||||
|
||||
### Dispose <a name="segmentedpool-dispose"></a>
|
||||
|
||||
Releases all unmanaged memory used by the pool and clears internal state.
|
||||
|
||||
#### Syntax
|
||||
|
||||
```csharp
|
||||
pool.Dispose();
|
||||
```
|
||||
|
||||
#### Parameters
|
||||
|
||||
None.
|
||||
|
||||
#### Return value
|
||||
|
||||
None.
|
||||
|
||||
#### Remarks
|
||||
|
||||
This method frees all active and free [Segments](#segments) so that after disposal, any memory allocated from the pool is invalid. This method is safe to call multiple times and calling any other public method after disposal is also safe.
|
||||
|
||||
Reference in New Issue
Block a user