英語版
このページの英語版を見る

std.experimental.allocator.building_blocks.quantizer

struct Quantizer(ParentAllocator, alias roundingFunction);
このアロケータはParentAllocator の上に置かれ、アロケーションサイズを量子化する、 このアロケータは の上に置かれ、割り当てサイズを量子化する。 2の累乗、ページサイズなど)。このテクニックは一般的に次のような目的で使われる:
  • 要求されたメモリよりも多くのメモリを事前に割り当てておく。 後で再割り当てが必要になったときに(たとえば配列を大きくするために)、その場で素早く拡張できるようにする。 を素早く行うことができる。要求された新しいサイズが、配列のサイズと同じ量子の範囲内であれば、小さいサイズへの再割り当ても(インプレースで)高速に行える。 要求された新しいサイズが既存のサイズと同じ量子の範囲内である場合、小さいサイズへの再割り当ても(インプレースで)高速に行われる。そのため 再割り当てを多用するコードは、汎用アロケータに a Quantizer.これらの利点は、ParentAllocator 。 が再割り当てをまったくサポートしていなくても、この利点は存在する。
  • のようなアロケーションサイズに敏感なアロケータの動作を改善する。 FreeListFreeTree のような、アロケーションサイズに敏感なアロケータの動作を改善する。アロケーションリクエストを四捨五入することで アロケーションリクエストを切り上げることで、空きリスト/ツリーが小さくなる。
以下のメソッドは、もし存在すれば親アロケータに転送される: allocateAll owns,deallocateAll,empty.

前提条件 roundingFunction は3つの制約を満たさなければならない。これらは効率化のため( を除いて)強制されない。 assertを使用する場合を除き)、効率のために強制されない。

  1. roundingFunction(n) >= n size_t のすべての に対してである;n
  2. roundingFunction は単調増加型でなければならない、すなわち for all でなければならない;roundingFunction(n1) <= roundingFunction(n2) n1 < n2
  3. roundingFunction は 、 、 、 でなければならない。 与えられた に対して常に同じ値を返す。nothrow @safe @nogc pure n

Examples:
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);
ParentAllocator parent;
親アロケータである。ParentAllocator 。 を保持しているかどうかによって、これはメンバ変数か ParentAllocator.instance.
size_t goodAllocSize(size_t n);
を返す。 roundingFunction(n).
enum auto alignment;
アライメントは親のものと同じである。
void[] allocate(size_t n);
を呼び出すことで、より大きなバッファbufparent.allocate(goodAllocSize(n)).bufnull の場合、以下を返す。 null.そうでない場合は、buf[0 .. n] を返す。
void[] alignedAllocate(size_t n, uint a);
が存在する場合にのみ定義される。 parent.alignedAllocateが存在する場合にのみ定義され allocate に転送することで parent.alignedAllocate(goodAllocSize(n), a).
bool expand(ref void[] b, size_t delta);
に転送することで同様に動作する。 b b.length + delta <= goodAllocSize(b.length) を評価する。もしそうなら であれば bを実行する。そうでない場合は parent.expandを適切に使用しようとする。
bool reallocate(ref void[] b, size_t s);
割り当てられたブロックを、割り当てられたサイズ goodAllocSize(s) に拡張または縮小する。 expand によって要求される。縮小は、goodAllocSize(b.length) == goodAllocSize(s) の場合、その場で行われる。
bool alignedReallocate(ref void[] b, size_t s, uint a);
ParentAllocator.alignedAllocate が存在する場合にのみ定義される。拡張 expand 。収縮 は、goodAllocSize(b.length) == goodAllocSize(s) が存在する場合、その場で起こる。
bool deallocate(void[] b);
以下の場合に定義される。 ParentAllocator.deallocateが存在し parent.deallocate(b.ptr[0 .. goodAllocSize(b.length)]).