View source code
Display the source code in std/experimental/allocator/building_blocks/quantizer.d from which this
page was generated on github.
Report a bug
If you spot a problem with this page, click here to create a
Bugzilla issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page.
Requires a signed-in GitHub account. This works well for small changes.
If you'd like to make larger changes you may want to consider using
local clone.
Struct std.experimental.allocator.building_blocks.quantizer.Quantizer
This allocator sits on top of ParentAllocator
and quantizes allocation sizes,
usually from arbitrary positive numbers to a small set of round numbers (e.g.
powers of two, page sizes etc). This technique is commonly used to:
struct Quantizer(ParentAllocator, alias roundingFunction)
;
- Preallocate more memory than requested such that later on, when
reallocation is needed (e.g. to grow an array), expansion can be done quickly
in place. Reallocation to smaller sizes is also fast (in-place) when the new
size requested is within the same quantum as the existing size. Code that's
reallocation-heavy can therefore benefit from fronting a generic allocator with
a
Quantizer
. These advantages are present even ifParentAllocator
does not support reallocation at all. - Improve behavior of allocators sensitive to allocation sizes, such as
FreeList
andFreeTree
. Rounding allocation requests up makes for smaller free lists/trees at the cost of slack memory (internal fragmentation).
The following methods are forwarded to the parent allocator if present:
allocateAll
, owns
, deallocateAll
, empty
.
Fields
Name | Type | Description |
---|---|---|
parent
|
ParentAllocator | The parent allocator. Depending on whether ParentAllocator holds state
or not, this is a member variable or an alias for
ParentAllocator .
|
Methods
Name | Description |
---|---|
alignedAllocate
(n, a)
|
Defined only if parent exists and works similarly to
allocate by forwarding to
parent .
|
alignedReallocate
(b, s, a)
|
Defined only if ParentAllocator exists. Expansion
occurs in place under the conditions required by expand . Shrinking
occurs in place if goodAllocSize(b .
|
allocate
(n)
|
Gets a larger buffer buf by calling
parent . If buf is null , returns
null . Otherwise, returns buf[0 .. n] .
|
deallocate
(b)
|
Defined if ParentAllocator exists and forwards to
parent .
|
expand
(b, delta)
|
First checks whether there's enough slack memory preallocated for b
by evaluating b . If that's
the case, expands b in place. Otherwise, attempts to use
parent appropriately if present.
|
goodAllocSize
(n)
|
Returns roundingFunction(n) .
|
reallocate
(b, s)
|
Expands or shrinks allocated block to an allocated size of goodAllocSize(s) . Expansion occurs in place under the conditions required
by expand . Shrinking occurs in place if goodAllocSize(b .
|
Preconditions
roundingFunction
must satisfy three constraints. These are
not enforced (save for the use of assert
) for the sake of efficiency.
roundingFunction(n) >= n
for alln
of typesize_t
;roundingFunction
must be monotonically increasing, i.e.roundingFunction(n1) <= roundingFunction(n2)
for alln1 < n2
;roundingFunction
must benothrow
,@safe
,@nogc
andpure
, i.e. always return the same value for a givenn
.
Example
import std .experimental .allocator .building_blocks .free_tree : FreeTree;
import std .experimental .allocator .gc_allocator : GCAllocator;
size_t roundUpToMultipleOf(size_t s, uint base)
{
auto rem = s % base;
return rem ? s + base - rem : s;
}
// Quantize small allocations to a multiple of cache line, large ones to a
// multiple of page size
alias MyAlloc = Quantizer!(
FreeTree!GCAllocator,
n => roundUpToMultipleOf(n, n <= 16_384 ? 64 : 4096));
MyAlloc alloc;
const buf = alloc .allocate(256);
assert(buf .ptr);
Authors
License
Copyright © 1999-2022 by the D Language Foundation | Page generated by ddox.