A game about forced loneliness, made by TACStudios
1using NUnit.Framework;
2using UnityEngine;
3using Unity.Collections.LowLevel.Unsafe;
4using Unity.PerformanceTesting;
5using Unity.PerformanceTesting.Benchmark;
6using System.Runtime.CompilerServices;
7using System.Threading;
8
9namespace Unity.Collections.PerformanceTests
10{
11 static class QueueParallelUtil
12 {
13 static public void AllocInt(ref NativeQueue<int> container, int capacity, bool addValues)
14 => QueueUtil.AllocInt(ref container, capacity, addValues);
15
16 static public object AllocBclContainer(int capacity, bool addValues)
17 {
18 if (capacity < 0)
19 return null;
20
21 Random.InitState(0);
22 var bclContainer = new System.Collections.Concurrent.ConcurrentQueue<int>();
23 if (addValues)
24 {
25 for (int i = 0; i < capacity; i++)
26 bclContainer.Enqueue(i);
27 }
28 return bclContainer;
29 }
30 }
31
32 struct QueueParallelEnqueueGrow : IBenchmarkContainerParallel
33 {
34 int capacity;
35 int workers;
36 NativeQueue<int> nativeContainer;
37
38 void IBenchmarkContainerParallel.SetParams(int capacity, params int[] args)
39 {
40 this.capacity = capacity;
41 workers = args[0];
42 }
43
44 public void AllocNativeContainer(int capacity) => QueueParallelUtil.AllocInt(ref nativeContainer, capacity >= 0 ? 0 : -1, false);
45 public void AllocUnsafeContainer(int capacity) { }
46 public object AllocBclContainer(int capacity) => QueueParallelUtil.AllocBclContainer(0, false);
47
48 public void MeasureNativeContainer(int worker, int threadId)
49 {
50 var writer = nativeContainer.AsParallelWriter();
51 ParallelHashMapUtil.SplitForWorkers(capacity, worker, workers, out int start, out int end);
52 for (int i = start; i < end; i++)
53 writer.Enqueue(i, threadId);
54 }
55 public void MeasureUnsafeContainer(int worker, int threadId) { }
56 public void MeasureBclContainer(object container, int worker)
57 {
58 var bclContainer = (System.Collections.Concurrent.ConcurrentQueue<int>)container;
59 ParallelHashMapUtil.SplitForWorkers(capacity, worker, workers, out int start, out int end);
60 for (int i = start; i < end; i++)
61 bclContainer.Enqueue(i);
62 }
63 }
64
65 struct QueueParallelEnqueue : IBenchmarkContainerParallel
66 {
67 int capacity;
68 int workers;
69 NativeQueue<int> nativeContainer;
70
71 void IBenchmarkContainerParallel.SetParams(int capacity, params int[] args)
72 {
73 this.capacity = capacity;
74 workers = args[0];
75 }
76
77 public void AllocNativeContainer(int capacity) => QueueParallelUtil.AllocInt(ref nativeContainer, capacity, false);
78 public void AllocUnsafeContainer(int capacity) { }
79 public object AllocBclContainer(int capacity) => QueueParallelUtil.AllocBclContainer(capacity, false);
80
81 public void MeasureNativeContainer(int worker, int threadId)
82 {
83 var writer = nativeContainer.AsParallelWriter();
84 ParallelHashMapUtil.SplitForWorkers(capacity, worker, workers, out int start, out int end);
85 for (int i = start; i < end; i++)
86 writer.Enqueue(i, threadId);
87 }
88 public void MeasureUnsafeContainer(int worker, int threadId) { }
89 public void MeasureBclContainer(object container, int worker)
90 {
91 var bclContainer = (System.Collections.Concurrent.ConcurrentQueue<int>)container;
92 ParallelHashMapUtil.SplitForWorkers(capacity, worker, workers, out int start, out int end);
93 for (int i = start; i < end; i++)
94 bclContainer.Enqueue(i);
95 }
96 }
97
98
99
100 [Benchmark(typeof(BenchmarkContainerType))]
101 [BenchmarkNameOverride(BenchmarkContainerConfig.BCL, "ConcurrentQueue")]
102 class QueueParallelWriter
103 {
104#if UNITY_EDITOR
105 [UnityEditor.MenuItem(BenchmarkContainerConfig.kMenuItemIndividual + "Queue.ParallelWriter")]
106 static void RunIndividual()
107 => BenchmarkContainerConfig.RunBenchmark(typeof(QueueParallelWriter));
108#endif
109
110 [Test, Performance]
111 [Category("Performance")]
112 [BenchmarkTestFootnote]
113 public unsafe void EnqueueGrow(
114 [Values(1, 2, 4)] int workers,
115 [Values(10000, 100000, 1000000)] int insertions,
116 [Values(BenchmarkContainerType.Native, BenchmarkContainerType.NativeBurstSafety,
117 BenchmarkContainerType.NativeBurstNoSafety)] BenchmarkContainerType type)
118 {
119 BenchmarkContainerRunnerParallel<QueueParallelEnqueueGrow>.Run(workers, insertions, type, workers);
120 }
121
122 [Test, Performance]
123 [Category("Performance")]
124 [BenchmarkTestFootnote]
125 public unsafe void Enqueue(
126 [Values(1, 2, 4)] int workers,
127 [Values(10000, 100000, 1000000)] int insertions,
128 [Values(BenchmarkContainerType.Native, BenchmarkContainerType.NativeBurstSafety,
129 BenchmarkContainerType.NativeBurstNoSafety)] BenchmarkContainerType type)
130 {
131 BenchmarkContainerRunnerParallel<QueueParallelEnqueue>.Run(workers, insertions, type, workers);
132 }
133 }
134}