How to destruct class instances allocated by a Region-allocator over a single GC block
Per Nordlöw
per.nordlow at gmail.com
Mon Apr 2 14:52:34 UTC 2018
As a follow-up to
https://forum.dlang.org/post/jfgpngdudtprzznrckwf@forum.dlang.org
I managed to put together the benchmark
https://github.com/nordlow/phobos-next/blob/fa3526b15c746bda50a195f4e492ab2de9c15287/benchmarks/allocators/source/app.d
which run (via ldc)
dub run --build=release-nobounds
prints
DoubleNode Region allocator: 103 ms and 810 μs
DoubleNode new-allocation: 2 secs, 565 ms, and 566 μs
DoubleNode with global allocator: 2 secs, 680 ms, and 93 μs
...
proving the massive speedups possible when using, for instance, a
Region allocator over a single continuous memory block, in this
case allocated by the GC.
The code tested is in essence the performance of 10 million
consecutive calls to the factory function `make` constructing
instances of the class `DoubleNode`:
void benchmarkAllocatorsRegion()
{
immutable nodeCount = 10_000_000; // number of `Nodes`s to
allocate
void[] buf = GCAllocator.instance.allocate(nodeCount *
__traits(classInstanceSize, DoubleNode));
auto allocator = Region!(NullAllocator,
platformAlignment)(cast(ubyte[])buf);
Type make(Type, Args...)(Args args) // TODO this should be
pure
{
pragma(inline, true);
return allocator.make!Type(args);
}
void[] allocate(size_t bytes)
{
return allocator.allocate(bytes); // TODO should be @safe
pure
}
/* latest pointer here to prevent fast scoped non-GC
allocation in LDC */
void* latestPtr;
void testRegionAllocator()
{
auto x = make!DoubleNode(42);
assert(x);
latestPtr = cast(void*)x;
}
void testNewAllocation()
{
auto x = new DoubleNode(42);
latestPtr = cast(void*)x;
}
void testGlobalAllocator()
{
auto x = theAllocator.make!DoubleNode(42);
latestPtr = cast(void*)x;
}
const results = benchmark!(testRegionAllocator,
testNewAllocation,
testGlobalAllocator)(nodeCount);
writeln("DoubleNode Region allocator: ", results[0]);
writeln("DoubleNode new-allocation: ", results[1]);
writeln("DoubleNode with global allocator: ", results[2]);
}
However, I can't figure out how we can be sure that the
destructors of `DoubleNode` are called for all the 10 million
objects. Is there a way to tell the GC where the class instances
that need to be destroyed lie (when nothing references them
anymore).
More information about the Digitalmars-d-learn
mailing list