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

std.experimental.allocator.building_blocks.aligned_block_list

AlignedBlockList アロケータチェーンのラッパーを表し、高速なデアロケーションを可能にする。 また、アライメントされたアロケーションにより、フラグメンテーションの程度を低く保つことができる。
struct AlignedBlockList(Allocator, ParentAllocator, ulong theAlignment = 1 << 21);
AlignedBlockListは、アロケータ・チェーンのラッパーを表し、高速なデアロケーションを可能にし、整列されたアロケーションによって低いフラグメンテーションを維持する。 を可能にし、フラグメンテーションの度合いを低く保つ。 アロケータは、Allocator オブジェクトの二重リンクリストを内部的に保持する。 を最も最近使われた方法で提供する。allocate 、最も最近使われたアロケータがリストの先頭に移動する。 リストの先頭に移動する。
理論的には、アロケーションは線形探索時間で処理されるが、deallocate の呼び出しには、次のような時間がかかる。 ParentAllocator &Omicron;(1)の時間がかかる。これは、アラインされたアロケーショ ンを使用するためである。alignedAllocate を実装し、theAlignment バイトを同じアライメントで割り当てることができなければならない。。 ParentAllocator Allocator 、その後にペイロードが続く。
Parameters:
Allocator を受け取るコンストラクタを持たなければならない。 ubyte[] を受け取るコンストラクタを持たなければならない。NullAllocator
ParentAllocator 各ノードは親アロケータからメモリを引き出す。alignedAllocate
theAlignment 各ブロックのアラインメントをサポートし、同時に各ノードの長さをサポートしなければならない。
Examples:
import std.experimental.allocator.building_blocks.ascending_page_allocator : AscendingPageAllocator;
import std.experimental.allocator.building_blocks.segregator : Segregator;
import std.experimental.allocator.building_blocks.bitmapped_block : BitmappedBlock;
import std.typecons : Ternary;

/*
In this example we use 'AlignedBlockList' in conjunction with other allocators
in order to create a more complex allocator.

The 'SuperAllocator' uses a 'Segregator' to distribute allocations to sub-allocators,
based on the requested size.

Each sub-allocator is represented by an 'AlignedBlockList' of 'BitmappedBlocks'.
Each 'AlignedBlockList' draws memory from a root allocator which in this case is an 'AscendingPageAllocator'

Such an allocator not only provides good performance, but also a low degree of memory fragmentation.
*/
alias SuperAllocator = Segregator!(
    32,
    AlignedBlockList!(BitmappedBlock!32, AscendingPageAllocator*, 1 << 12),
    Segregator!(

    64,
    AlignedBlockList!(BitmappedBlock!64, AscendingPageAllocator*, 1 << 12),
    Segregator!(

    128,
    AlignedBlockList!(BitmappedBlock!128, AscendingPageAllocator*, 1 << 12),
    AscendingPageAllocator*
)));

SuperAllocator a;
auto pageAlloc = AscendingPageAllocator(128 * 4096);

// Set the parent allocator for all the sub allocators
a.allocatorForSize!256 = &pageAlloc;
a.allocatorForSize!128.parent = &pageAlloc;
a.allocatorForSize!64.parent = &pageAlloc;
a.allocatorForSize!32.parent = &pageAlloc;

enum testNum = 10;
void[][testNum] buf;

// Allocations of size 32 will go to the first 'AlignedBlockList'
foreach (j; 0 .. testNum)
{
    buf[j] = a.allocate(32);
    writeln(buf[j].length); // 32

    // This is owned by the first 'AlignedBlockList'
    writeln(a.allocatorForSize!32.owns(buf[j])); // Ternary.yes
}

// Free the memory
foreach (j; 0 .. testNum)
    assert(a.deallocate(buf[j]));

// Allocations of size 64 will go to the second 'AlignedBlockList'
foreach (j; 0 .. testNum)
{
    buf[j] = a.allocate(64);
    writeln(buf[j].length); // 64

    // This is owned by the second 'AlignedBlockList'
    writeln(a.allocatorForSize!64.owns(buf[j])); // Ternary.yes
}

// Free the memory
foreach (j; 0 .. testNum)
    assert(a.deallocate(buf[j]));

// Allocations of size 128 will go to the third 'AlignedBlockList'
foreach (j; 0 .. testNum)
{
    buf[j] = a.allocate(128);
    writeln(buf[j].length); // 128

    // This is owned by the third 'AlignedBlockList'
    writeln(a.allocatorForSize!128.owns(buf[j])); // Ternary.yes
}

// Free the memory
foreach (j; 0 .. testNum)
    assert(a.deallocate(buf[j]));

// Allocations which exceed 128, will go to the 'AscendingPageAllocator*'
void[] b = a.allocate(256);
writeln(b.length); // 256
a.deallocate(b);
void[] allocate(size_t n);
サイズのメモリチャンクを返す n AlignedBlockNode リストから、利用可能なメモリーを持つ最初のノードを見つける、 それをリストの先頭に移動する。
新しいメモリを返せない空のノードはすべてリストから削除される。
Parameters:
size_t n 割り当てるバイト数
Returns:
必要な長さのメモリチャンクか、失敗時にnull
bool deallocate(void[] b);
パラメータとして与えられた bを解放する。解放はリスト内のノード数に関係なく、一定の 時間で行われる。 b.ptrは切り捨てられる。 alignment の倍数に切り捨てられる。 AlignedBlockNode.
Parameters:
void[] b バッファ候補を素早く見つけることができる。
Returns:
true 成功した場合、失敗した場合は を返すfalse
Ternary owns(void[] b);
バッファが親アロケータに属していればTernary.yes を返し、そうでなければ Ternary.no それ以外の場合は
Parameters:
void[] b バッファがこのアロケータに属しているかテストされる
Returns:
Ternary.yes このアロケータが所有していればテストされ、そうでなければ である。Ternary.no
struct SharedAlignedBlockList(Allocator, ParentAllocator, ulong theAlignment = 1 << 21);
SharedAlignedBlockListAlignedBlockList のスレッドセーフ版である。 Allocator テンプレート・パラメータは共有アロケータを参照しなければならない。 また、ParentAllocator は、alignedAllocate をサポートする共有アロケータでなければならない。
Parameters:
Allocator を受け取るコンストラクタを持たなければならない。 ubyte[] を受け取るコンストラクタを持たなければならない。NullAllocator
ParentAllocator 各ノードは親アロケータからメモリを引き出す。alignedAllocate
theAlignment 各ブロックのアラインメントと各ノードの長さを同時にサポートしなければならない。
Examples:
import std.experimental.allocator.building_blocks.region : SharedBorrowedRegion;
import std.experimental.allocator.building_blocks.ascending_page_allocator : SharedAscendingPageAllocator;
import std.experimental.allocator.building_blocks.null_allocator : NullAllocator;
import core.thread : ThreadGroup;

enum numThreads = 8;
enum size = 2048;
enum maxIter = 10;

/*
In this example we use 'SharedAlignedBlockList' together with
'SharedBorrowedRegion', in order to create a fast, thread-safe allocator.
*/
alias SuperAllocator = SharedAlignedBlockList!(
        SharedBorrowedRegion!(1),
        SharedAscendingPageAllocator,
        4096);

SuperAllocator a;
// The 'SuperAllocator' will draw memory from a 'SharedAscendingPageAllocator'
a.parent = SharedAscendingPageAllocator(4096 * 1024);

// Launch 'numThreads', each performing allocations
void fun()
{
    foreach (i; 0 .. maxIter)
    {
        void[] b = a.allocate(size);
        writeln(b.length); // size
    }
}

auto tg = new ThreadGroup;
foreach (i; 0 .. numThreads)
{
    tg.create(&fun);
}
tg.joinAll();
void[] allocate(size_t n);
サイズのメモリチャンクを返す n AlignedBlockNode リストから、利用可能なメモリーを持つ最初のノードを見つける、 それをリストの先頭に移動する。
新しいメモリを返せない空のノードはすべてリストから削除される。
Parameters:
size_t n 割り当てるバイト数
Returns:
必要な長さのメモリチャンクか、失敗時にnull
bool deallocate(void[] b);
パラメータとして与えられた bを解放する。解放はリスト内のノード数に関係なく、一定の 時間で行われる。 b.ptrは切り捨てられる。 alignment の倍数に切り捨てられる。 AlignedBlockNode.
Parameters:
void[] b バッファ候補を素早く見つけることができる。
Returns:
true 成功した場合、失敗した場合は を返すfalse
Ternary owns(void[] b);
バッファが親アロケータに属していればTernary.yes を返し、そうでなければ Ternary.no それ以外の場合は
Parameters:
void[] b バッファがこのアロケータに属しているかテストされる
Returns:
Ternary.yes このアロケータが所有していればテストされ、そうでなければ である。Ternary.no