A game about forced loneliness, made by TACStudios
1using NUnit.Framework;
2using System;
3using System.Runtime.CompilerServices;
4using Unity.PerformanceTesting;
5using Unity.PerformanceTesting.Benchmark;
6
7namespace Unity.Collections.PerformanceTests
8{
9 struct RewindableAllocationInfo
10 {
11 public AllocatorHelper<RewindableAllocator> customAllocator;
12 BenchmarkAllocatorUtil allocInfo;
13 AllocatorManager.AllocatorHandle allocatorHandle;
14
15 public void CreateAllocator(Allocator builtinOverride)
16 {
17 if (builtinOverride != Allocator.None)
18 allocatorHandle = builtinOverride;
19 else
20 {
21 customAllocator = new AllocatorHelper<RewindableAllocator>(Allocator.Persistent);
22 customAllocator.Allocator.Initialize(128 * 1024, true);
23 allocatorHandle = customAllocator.Allocator.Handle;
24 }
25 }
26
27 public void DestroyAllocator()
28 {
29 if (allocatorHandle.IsCustomAllocator)
30 {
31 customAllocator.Allocator.Dispose();
32 customAllocator.Dispose();
33 }
34 allocatorHandle = Allocator.Invalid;
35 }
36
37 public void Setup(int workers, int baseSize, int growthRate, int allocations)
38 {
39 allocInfo.Setup(workers, baseSize, growthRate, allocations);
40 }
41
42 public void Teardown()
43 {
44 allocInfo.Teardown(allocatorHandle);
45
46 // Here we presume allocatorHandle == customAllocator.Handle, though there's currently no functionality
47 // to check that in custom allocatorHandle API
48 if (allocatorHandle.IsCustomAllocator)
49 {
50 customAllocator.Allocator.Rewind();
51
52 // Rewinding invalidates the handle, so reassign
53 allocatorHandle = customAllocator.Allocator.Handle;
54 }
55 }
56
57 unsafe public void Allocate(int workerI)
58 {
59 var inner = allocInfo.AllocPtr[workerI];
60 for (int i = 0; i < inner.Length; i++)
61 inner[i] = (IntPtr)AllocatorManager.Allocate(allocatorHandle, allocInfo.AllocSize[i], 0);
62 }
63 }
64
65 struct Rewindable_FixedSize : IBenchmarkAllocator
66 {
67 RewindableAllocationInfo allocInfo;
68
69 public void CreateAllocator(Allocator builtinOverride) => allocInfo.CreateAllocator(builtinOverride);
70 public void DestroyAllocator() => allocInfo.DestroyAllocator();
71 public void Setup(int workers, int size, int allocations) =>
72 allocInfo.Setup(workers, size, 0, allocations);
73 public void Teardown() => allocInfo.Teardown();
74 public void Measure(int workerI) => allocInfo.Allocate(workerI);
75 }
76
77 struct Rewindable_IncSize : IBenchmarkAllocator
78 {
79 RewindableAllocationInfo allocInfo;
80
81 public void CreateAllocator(Allocator builtinOverride) => allocInfo.CreateAllocator(builtinOverride);
82 public void DestroyAllocator() => allocInfo.DestroyAllocator();
83 public void Setup(int workers, int size, int allocations) =>
84 allocInfo.Setup(workers, size, size, allocations);
85 public void Teardown() => allocInfo.Teardown();
86 public void Measure(int workerI) => allocInfo.Allocate(workerI);
87 }
88
89 struct Rewindable_DecSize : IBenchmarkAllocator
90 {
91 RewindableAllocationInfo allocInfo;
92
93 public void CreateAllocator(Allocator builtinOverride) => allocInfo.CreateAllocator(builtinOverride);
94 public void DestroyAllocator() => allocInfo.DestroyAllocator();
95 public void Setup(int workers, int size, int allocations) =>
96 allocInfo.Setup(workers, size, -size, allocations);
97 public void Teardown() => allocInfo.Teardown();
98 public void Measure(int workerI) => allocInfo.Allocate(workerI);
99 }
100
101
102 [Benchmark(typeof(BenchmarkAllocatorType))]
103 [BenchmarkNameOverride("RewindableAllocator")]
104 class RewindableAllocatorBenchmark
105 {
106 [Test, Performance]
107 [Category("Performance")]
108 [BenchmarkTestFootnote]
109 public void FixedSize(
110 [Values(1, 2, 4, 8)] int workerThreads,
111 [Values(1024, 1024 * 1024)] int allocSize,
112 [Values] BenchmarkAllocatorType type)
113 {
114 BenchmarkAllocatorRunner<Rewindable_FixedSize>.Run(type, allocSize, workerThreads);
115 }
116
117 [Test, Performance]
118 [Category("Performance")]
119 [BenchmarkTestFootnote("Makes linearly increasing allocations [1⋅allocSize, 2⋅allocSize ... N⋅allocSize]")]
120 public void IncSize(
121 [Values(1, 2, 4, 8)] int workerThreads,
122 [Values(4096, 65536)] int allocSize,
123 [Values] BenchmarkAllocatorType type)
124 {
125 BenchmarkAllocatorRunner<Rewindable_IncSize>.Run(type, allocSize, workerThreads);
126 }
127
128 [Test, Performance]
129 [Category("Performance")]
130 [BenchmarkTestFootnote("Makes linearly decreasing allocations [N⋅allocSize ... 2⋅allocSize, 1⋅allocSize]")]
131 public void DecSize(
132 [Values(1, 2, 4, 8)] int workerThreads,
133 [Values(4096, 65536)] int allocSize,
134 [Values] BenchmarkAllocatorType type)
135 {
136 BenchmarkAllocatorRunner<Rewindable_DecSize>.Run(type, allocSize, workerThreads);
137 }
138 }
139}