Пример #1
0
 /// <summary>
 /// Creates a new memory pool.
 /// </summary>
 /// <param name="memoryPoolSize">Size of the pool in elements.</param>
 public Allocator(long memoryPoolSize, int allocationCountEstimate = 128)
 {
     this.Capacity = memoryPoolSize;
     QuickDictionary <ulong, Allocation, Array <ulong>, Array <Allocation>, Array <int>, PrimitiveComparer <ulong> > .Create(
         new PassthroughArrayPool <ulong>(), new PassthroughArrayPool <Allocation>(), new PassthroughArrayPool <int>(),
         SpanHelper.GetContainingPowerOf2(allocationCountEstimate), 3, out allocations);
 }
        public SimulationProfiler(int initialStageCount = 8)
        {
            QuickDictionary <object, double, Array <object>, Array <double>, Array <int>, ReferenceComparer <object> > .Create(
                objectPool, doublePool, intPool, SpanHelper.GetContainingPowerOf2(initialStageCount), 3, out stages);

            QuickDictionary <object, long, Array <object>, Array <long>, Array <int>, ReferenceComparer <object> > .Create(
                objectPool, longPool, intPool, SpanHelper.GetContainingPowerOf2(initialStageCount), 3, out startTimeStamps);
        }
        public static void TestDictionaryResizing <TSpan, TPool>(TPool pool)
            where TSpan : ISpan <int>
            where TPool : IMemoryPool <int, TSpan>
        {
            Random random = new Random(5);

            QuickDictionary <int, int, TSpan, TSpan, TSpan, PrimitiveComparer <int> > .Create(pool, pool, pool, 2, 3, out var dictionary);

            Dictionary <int, int> controlDictionary = new Dictionary <int, int>();

            for (int iterationIndex = 0; iterationIndex < 100000; ++iterationIndex)
            {
                if (random.NextDouble() < 0.7)
                {
                    dictionary.Add(iterationIndex, iterationIndex, pool, pool, pool);
                    controlDictionary.Add(iterationIndex, iterationIndex);
                }
                if (random.NextDouble() < 0.2)
                {
                    var indexToRemove = random.Next(dictionary.Count);
                    var toRemove      = dictionary.Keys[indexToRemove];
                    dictionary.FastRemove(toRemove);
                    controlDictionary.Remove(toRemove);
                }
                if (iterationIndex % 1000 == 0)
                {
                    dictionary.EnsureCapacity(dictionary.Count * 3, pool, pool, pool);
                }
                else if (iterationIndex % 7777 == 0)
                {
                    dictionary.Compact(pool, pool, pool);
                }
            }

            Debug.Assert(dictionary.Count == controlDictionary.Count);
            for (int i = 0; i < dictionary.Count; ++i)
            {
                Debug.Assert(controlDictionary.ContainsKey(dictionary.Keys[i]));
            }
            foreach (var element in controlDictionary.Keys)
            {
                Debug.Assert(dictionary.ContainsKey(element));
            }
            dictionary.Dispose(pool, pool, pool);
        }
Пример #4
0
        public unsafe void Render(DeviceContext context, Camera camera, Int2 screenResolution, MeshInstance[] instances, int start, int count)
        {
            //Examine the set of instances and batch them into groups using the same mesh data.
            var keyPool      = meshCache.Pool.SpecializeFor <ulong>();
            var valuePool    = meshCache.Pool.SpecializeFor <QuickList <MeshInstance, Buffer <MeshInstance> > >();
            var tablePool    = meshCache.Pool.SpecializeFor <int>();
            var instancePool = meshCache.Pool.SpecializeFor <MeshInstance>();

            //(but is this ENOUGH generics?)
            QuickDictionary <
                ulong, QuickList <MeshInstance,
                                  Buffer <MeshInstance> >, Buffer <ulong>,
                Buffer <QuickList <MeshInstance, Buffer <MeshInstance> > >, Buffer <int>,
                PrimitiveComparer <ulong> > .Create(keyPool, valuePool, tablePool, 4, 3, out var batches);

            var end = start + count;

            for (int i = start; i < end; ++i)
            {
                ref var instance = ref instances[i];
                ref var id       = ref Unsafe.As <int, ulong>(ref instance.VertexStart);
        public static void Test()
        {
            //var random = new Random(5);
            //var comparer = new CollidablePairComparer();
            //for (int i = 0; i < 10000; ++i)
            //{
            //    var a = new CollidableReference((CollidableMobility)random.Next(3), random.Next(1 << 30));
            //    var b = new CollidableReference((CollidableMobility)random.Next(3), random.Next(1 << 30));
            //    var pair1 = new CollidablePair(a, b);
            //    var pair2 = new CollidablePair(b, a);
            //    Debug.Assert(comparer.Hash(ref pair1) == comparer.Hash(ref pair2));
            //    Debug.Assert(comparer.Equals(ref pair1, ref pair2));
            //}
            //for (int i = 0; i < 10000; ++i)
            //{
            //    var a = new CollidableReference((CollidableMobility)random.Next(3), random.Next(1 << 30));
            //    var b = new CollidableReference((CollidableMobility)random.Next(3), random.Next(1 << 30));
            //    var pair1 = new CollidablePair(a, b);
            //    CollidablePair pair2;
            //    do
            //    {
            //        var a2 = new CollidableReference((CollidableMobility)random.Next(3), random.Next(1 << 30));
            //        var b2 = new CollidableReference((CollidableMobility)random.Next(3), random.Next(1 << 30));
            //        pair2 = new CollidablePair(a2, b2);
            //    } while (
            //    (pair2.A.Packed == pair1.A.Packed && pair2.B.Packed == pair1.B.Packed) ||
            //    (pair2.B.Packed == pair1.A.Packed && pair2.A.Packed == pair1.B.Packed));
            //    Debug.Assert(!comparer.Equals(ref pair1, ref pair2));
            //}


            const int iterationCount          = 1000;
            const int perLayerCollidableCount = 900;
            const int layerCount = 10;

            int[] creationRemap = new int[perLayerCollidableCount * (layerCount - 1)];
            int[] lookupRemap   = new int[creationRemap.Length];
            for (int i = 0; i < creationRemap.Length; ++i)
            {
                creationRemap[i] = i;
                lookupRemap[i]   = i;
            }

            QuickDictionary <CollidablePair, int, Array <CollidablePair>, Array <int>, Array <int>, CollidablePairComparer> .Create(
                new PassthroughArrayPool <CollidablePair>(), new PassthroughArrayPool <int>(), new PassthroughArrayPool <int>(), SpanHelper.GetContainingPowerOf2(creationRemap.Length), 1,
                out var dictionary);

            var random = new Random(5);

            for (int i = 0; i < creationRemap.Length - 1; ++i)
            {
                {
                    var temp       = creationRemap[i];
                    var swapTarget = random.Next(i + 1, creationRemap.Length);
                    creationRemap[i]          = creationRemap[swapTarget];
                    creationRemap[swapTarget] = temp;
                }
                {
                    var temp       = lookupRemap[i];
                    var swapTarget = random.Next(i + 1, lookupRemap.Length);
                    lookupRemap[i]          = lookupRemap[swapTarget];
                    lookupRemap[swapTarget] = temp;
                }
            }

            int       accumulator      = 0;
            double    totalTime        = 0;
            const int warmupIterations = 128;

            for (int iterationIndex = 0; iterationIndex < iterationCount + warmupIterations; ++iterationIndex)
            {
                dictionary.Clear();
                for (int i = 0; i < creationRemap.Length; ++i)
                {
                    var index = creationRemap[i];
                    var pair  = new CollidablePair
                    {
                        A = new CollidableReference(CollidableMobility.Kinematic, index),
                        B = new CollidableReference(CollidableMobility.Dynamic, index + perLayerCollidableCount)
                    };
                    dictionary.AddUnsafely(ref pair, ref index);
                }
                CacheBlaster.Blast();
                //Prewarm the remap into cache to more closely mirror the behavior in the narrow phase.
                for (int i = 0; i < lookupRemap.Length; ++i)
                {
                    accumulator += lookupRemap[i];
                }
                var start = Stopwatch.GetTimestamp();
                for (int i = 0; i < lookupRemap.Length; ++i)
                {
                    var collidableIndex = lookupRemap[i];
                    var pair            = new CollidablePair
                    {
                        A = new CollidableReference(CollidableMobility.Kinematic, collidableIndex),
                        B = new CollidableReference(CollidableMobility.Dynamic, collidableIndex + perLayerCollidableCount)
                    };
                    var dictionaryIndex = dictionary.IndexOf(ref pair);
                    accumulator += dictionaryIndex;
                }
                var end = Stopwatch.GetTimestamp();
                if (iterationIndex >= warmupIterations)
                {
                    totalTime += (end - start) / (double)Stopwatch.Frequency;
                }
            }
            Console.WriteLine($"Time per lookup (ns): {1e9 * totalTime / (iterationCount * creationRemap.Length)}, acc{accumulator}");
        }