140 lines
5.2 KiB
C#
140 lines
5.2 KiB
C#
|
using NUnit.Framework;
|
||
|
using System;
|
||
|
using System.Runtime.CompilerServices;
|
||
|
using Unity.PerformanceTesting;
|
||
|
using Unity.PerformanceTesting.Benchmark;
|
||
|
|
||
|
namespace Unity.Collections.PerformanceTests
|
||
|
{
|
||
|
struct RewindableAllocationInfo
|
||
|
{
|
||
|
public AllocatorHelper<RewindableAllocator> customAllocator;
|
||
|
BenchmarkAllocatorUtil allocInfo;
|
||
|
AllocatorManager.AllocatorHandle allocatorHandle;
|
||
|
|
||
|
public void CreateAllocator(Allocator builtinOverride)
|
||
|
{
|
||
|
if (builtinOverride != Allocator.None)
|
||
|
allocatorHandle = builtinOverride;
|
||
|
else
|
||
|
{
|
||
|
customAllocator = new AllocatorHelper<RewindableAllocator>(Allocator.Persistent);
|
||
|
customAllocator.Allocator.Initialize(128 * 1024, true);
|
||
|
allocatorHandle = customAllocator.Allocator.Handle;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void DestroyAllocator()
|
||
|
{
|
||
|
if (allocatorHandle.IsCustomAllocator)
|
||
|
{
|
||
|
customAllocator.Allocator.Dispose();
|
||
|
customAllocator.Dispose();
|
||
|
}
|
||
|
allocatorHandle = Allocator.Invalid;
|
||
|
}
|
||
|
|
||
|
public void Setup(int workers, int baseSize, int growthRate, int allocations)
|
||
|
{
|
||
|
allocInfo.Setup(workers, baseSize, growthRate, allocations);
|
||
|
}
|
||
|
|
||
|
public void Teardown()
|
||
|
{
|
||
|
allocInfo.Teardown(allocatorHandle);
|
||
|
|
||
|
// Here we presume allocatorHandle == customAllocator.Handle, though there's currently no functionality
|
||
|
// to check that in custom allocatorHandle API
|
||
|
if (allocatorHandle.IsCustomAllocator)
|
||
|
{
|
||
|
customAllocator.Allocator.Rewind();
|
||
|
|
||
|
// Rewinding invalidates the handle, so reassign
|
||
|
allocatorHandle = customAllocator.Allocator.Handle;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
unsafe public void Allocate(int workerI)
|
||
|
{
|
||
|
var inner = allocInfo.AllocPtr[workerI];
|
||
|
for (int i = 0; i < inner.Length; i++)
|
||
|
inner[i] = (IntPtr)AllocatorManager.Allocate(allocatorHandle, allocInfo.AllocSize[i], 0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
struct Rewindable_FixedSize : IBenchmarkAllocator
|
||
|
{
|
||
|
RewindableAllocationInfo allocInfo;
|
||
|
|
||
|
public void CreateAllocator(Allocator builtinOverride) => allocInfo.CreateAllocator(builtinOverride);
|
||
|
public void DestroyAllocator() => allocInfo.DestroyAllocator();
|
||
|
public void Setup(int workers, int size, int allocations) =>
|
||
|
allocInfo.Setup(workers, size, 0, allocations);
|
||
|
public void Teardown() => allocInfo.Teardown();
|
||
|
public void Measure(int workerI) => allocInfo.Allocate(workerI);
|
||
|
}
|
||
|
|
||
|
struct Rewindable_IncSize : IBenchmarkAllocator
|
||
|
{
|
||
|
RewindableAllocationInfo allocInfo;
|
||
|
|
||
|
public void CreateAllocator(Allocator builtinOverride) => allocInfo.CreateAllocator(builtinOverride);
|
||
|
public void DestroyAllocator() => allocInfo.DestroyAllocator();
|
||
|
public void Setup(int workers, int size, int allocations) =>
|
||
|
allocInfo.Setup(workers, size, size, allocations);
|
||
|
public void Teardown() => allocInfo.Teardown();
|
||
|
public void Measure(int workerI) => allocInfo.Allocate(workerI);
|
||
|
}
|
||
|
|
||
|
struct Rewindable_DecSize : IBenchmarkAllocator
|
||
|
{
|
||
|
RewindableAllocationInfo allocInfo;
|
||
|
|
||
|
public void CreateAllocator(Allocator builtinOverride) => allocInfo.CreateAllocator(builtinOverride);
|
||
|
public void DestroyAllocator() => allocInfo.DestroyAllocator();
|
||
|
public void Setup(int workers, int size, int allocations) =>
|
||
|
allocInfo.Setup(workers, size, -size, allocations);
|
||
|
public void Teardown() => allocInfo.Teardown();
|
||
|
public void Measure(int workerI) => allocInfo.Allocate(workerI);
|
||
|
}
|
||
|
|
||
|
|
||
|
[Benchmark(typeof(BenchmarkAllocatorType))]
|
||
|
[BenchmarkNameOverride("RewindableAllocator")]
|
||
|
class RewindableAllocatorBenchmark
|
||
|
{
|
||
|
[Test, Performance]
|
||
|
[Category("Performance")]
|
||
|
[BenchmarkTestFootnote]
|
||
|
public void FixedSize(
|
||
|
[Values(1, 2, 4, 8)] int workerThreads,
|
||
|
[Values(1024, 1024 * 1024)] int allocSize,
|
||
|
[Values] BenchmarkAllocatorType type)
|
||
|
{
|
||
|
BenchmarkAllocatorRunner<Rewindable_FixedSize>.Run(type, allocSize, workerThreads);
|
||
|
}
|
||
|
|
||
|
[Test, Performance]
|
||
|
[Category("Performance")]
|
||
|
[BenchmarkTestFootnote("Makes linearly increasing allocations [1⋅allocSize, 2⋅allocSize ... N⋅allocSize]")]
|
||
|
public void IncSize(
|
||
|
[Values(1, 2, 4, 8)] int workerThreads,
|
||
|
[Values(4096, 65536)] int allocSize,
|
||
|
[Values] BenchmarkAllocatorType type)
|
||
|
{
|
||
|
BenchmarkAllocatorRunner<Rewindable_IncSize>.Run(type, allocSize, workerThreads);
|
||
|
}
|
||
|
|
||
|
[Test, Performance]
|
||
|
[Category("Performance")]
|
||
|
[BenchmarkTestFootnote("Makes linearly decreasing allocations [N⋅allocSize ... 2⋅allocSize, 1⋅allocSize]")]
|
||
|
public void DecSize(
|
||
|
[Values(1, 2, 4, 8)] int workerThreads,
|
||
|
[Values(4096, 65536)] int allocSize,
|
||
|
[Values] BenchmarkAllocatorType type)
|
||
|
{
|
||
|
BenchmarkAllocatorRunner<Rewindable_DecSize>.Run(type, allocSize, workerThreads);
|
||
|
}
|
||
|
}
|
||
|
}
|