Esempio n. 1
0
        public unsafe static TestResults TestSingleArray(TestCollidable[] leaves, BoundingBox[] queries, BoundingBox positionBounds,
                                                         int queryCount, int selfTestCount, int refitCount, int frameCount, float dt, ParallelLooper looper)
        {
            {
                var  warmLeaves = GetLeaves(10, 10, 10, 10, 10);
                Tree tree       = new Tree();
                //for (int i = 0; i < leaves.Length; ++i)
                //{
                //    BoundingBox box;
                //    leaves[i].GetBoundingBox(out box);
                //    //tree.Insert(i, ref box);
                //    tree.AddGlobal(i, ref box);
                //}
                int[]         leafIds    = new int[warmLeaves.Length];
                BoundingBox[] leafBounds = new BoundingBox[warmLeaves.Length];
                for (int i = 0; i < warmLeaves.Length; ++i)
                {
                    leafIds[i] = i;
                    warmLeaves[i].GetBoundingBox(out leafBounds[i]);
                }
                //tree.BuildMedianSplit(leafIds, leafBounds);
                //tree.BuildVolumeHeuristic(leafIds, leafBounds);
                tree.SweepBuild(leafIds, leafBounds);
                Console.WriteLine($"SingleArray Cachewarm Build: {tree.LeafCount}");

                tree.Refit();
                //tree.BottomUpAgglomerativeRefine();
                //tree.TopDownAgglomerativeRefine();
                //tree.BottomUpSweepRefine();
                //tree.TopDownSweepRefine();

                tree.RefitAndRefine(0);
                var context = new Tree.RefitAndRefineMultithreadedContext(tree);
                tree.RefitAndRefine(0, looper, context);

                var selfTestContext = new Tree.SelfTestMultithreadedContext(looper.ThreadCount, BufferPools <Overlap> .Locking);
                tree.GetSelfOverlaps(looper, selfTestContext);

                var         list = new QuickList <int>(new BufferPool <int>());
                BoundingBox aabb = new BoundingBox {
                    Min = new Vector3(0, 0, 0), Max = new Vector3(1, 1, 1)
                };
                tree.QueryRecursive(ref aabb, ref list);
                list.Dispose();

                var overlaps = new QuickList <Overlap>(new BufferPool <Overlap>());
                tree.GetSelfOverlaps(ref overlaps);

                overlaps = new QuickList <Overlap>(new BufferPool <Overlap>());
                tree.GetSelfOverlapsArityDedicated(ref overlaps);

                tree.IncrementalCacheOptimize(0);

                overlaps = new QuickList <Overlap>(new BufferPool <Overlap>());

                tree.GetSelfOverlapsViaQueries(ref overlaps);
                Console.WriteLine($"Cachewarm overlaps: {overlaps.Count}");
                tree.Dispose();
            }

            {
                Console.WriteLine($"SingleArray arity: {Tree.ChildrenCapacity}");
                Tree tree      = new Tree(Math.Max(1, leaves.Length));
                var  startTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                for (int i = 0; i < leaves.Length; ++i)
                {
                    var         leafIndex = (int)((982451653L * i) % leaves.Length);
                    BoundingBox box;
                    leaves[leafIndex].GetBoundingBox(out box);
                    tree.Add(leafIndex, ref box);
                    //tree.AddGlobal(leafIndex, ref box);
                }
                //int[] leafIds = new int[leaves.Length];
                //BoundingBox[] leafBounds = new BoundingBox[leaves.Length];
                //for (int i = 0; i < leaves.Length; ++i)
                //{
                //    leafIds[i] = i;
                //    leaves[i].GetBoundingBox(out leafBounds[i]);
                //}
                ////tree.BuildMedianSplit(leafIds, leafBounds);
                ////tree.BuildVolumeHeuristic(leafIds, leafBounds);
                //tree.SweepBuild(leafIds, leafBounds);
                var endTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                Console.WriteLine($"SingleArray Build Time: {endTime - startTime}, depth: {tree.ComputeMaximumDepth()}");

                int nodeCount, childCount;
                tree.MeasureNodeOccupancy(out nodeCount, out childCount);
                Console.WriteLine($"SingleArray Occupancy: {childCount / (double)nodeCount}");
                Console.WriteLine($"Cost metric: {tree.MeasureCostMetric()}");
                Console.WriteLine($"Cache Quality: {tree.MeasureCacheQuality()}");

                tree.Validate();

                startTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                for (int i = 0; i < refitCount; ++i)
                {
                    //for (int i = 0; i < tree.LeafCount; ++i)
                    //{
                    //    BoundingBox box;
                    //    leaves[tree.Leaves[i].Id].GetBoundingBox(out box);
                    //    tree.UpdateLeafBoundingBox(i, ref box);
                    //}
                    tree.Refit();
                }
                endTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                Console.WriteLine($"SingleArray Refit Time1: {endTime - startTime}");

                var overlaps = new QuickList <Overlap>(new BufferPool <Overlap>());
                startTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                for (int i = 0; i < selfTestCount; ++i)
                {
                    overlaps.Count = 0;
                    tree.GetSelfOverlaps(ref overlaps);
                }
                endTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                Console.WriteLine($"SingleArray SelfTree Time1: {endTime - startTime}, overlaps: {overlaps.Count}");


                int[]           buffer;
                MemoryRegion    region;
                BinnedResources resources;
                const int       maximumSubtrees      = 262144;
                var             spareNodes           = new QuickList <int>(new BufferPool <int>(), 8);
                var             subtreeReferences    = new QuickList <int>(BufferPools <int> .Thread, BufferPool <int> .GetPoolIndex(maximumSubtrees));
                var             treeletInternalNodes = new QuickList <int>(BufferPools <int> .Thread, BufferPool <int> .GetPoolIndex(maximumSubtrees));
                Tree.CreateBinnedResources(BufferPools <int> .Thread, maximumSubtrees, out buffer, out region, out resources);
                bool nodesInvalidated;
                overlaps = new QuickList <Overlap>(new BufferPool <Overlap>());

                var refineContext   = new Tree.RefitAndRefineMultithreadedContext(tree);
                var selfTestContext = new Tree.SelfTestMultithreadedContext(looper.ThreadCount, BufferPools <Overlap> .Locking);


                var visitedNodes = new QuickSet <int>(BufferPools <int> .Thread, BufferPools <int> .Thread);

                //**************** Dynamic Testing
                Random      random  = new Random(5);
                TestResults results = new TestResults("New", frameCount);
                startTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                for (int t = 0; t < frameCount; ++t)
                {
                    //Update the positions of objects.
                    for (int i = 0; i < tree.LeafCount; ++i)
                    {
                        var leafId = tree.Leaves[i].Id;
                        var leaf   = leaves[leafId];

                        //Bounce off the walls.
                        if (leaf.Position.X < positionBounds.Min.X && leaf.Velocity.X < 0)
                        {
                            leaf.Velocity.X = -leaf.Velocity.X;
                        }
                        if (leaf.Position.Y < positionBounds.Min.Y && leaf.Velocity.Y < 0)
                        {
                            leaf.Velocity.Y = -leaf.Velocity.Y;
                        }
                        if (leaf.Position.Z < positionBounds.Min.Z && leaf.Velocity.Z < 0)
                        {
                            leaf.Velocity.Z = -leaf.Velocity.Z;
                        }

                        if (leaf.Position.X > positionBounds.Max.X && leaf.Velocity.X > 0)
                        {
                            leaf.Velocity.X = -leaf.Velocity.X;
                        }
                        if (leaf.Position.Y > positionBounds.Max.Y && leaf.Velocity.Y > 0)
                        {
                            leaf.Velocity.Y = -leaf.Velocity.Y;
                        }
                        if (leaf.Position.Z > positionBounds.Max.Z && leaf.Velocity.Z > 0)
                        {
                            leaf.Velocity.Z = -leaf.Velocity.Z;
                        }

                        leaf.Position += leaf.Velocity * dt;
                        BoundingBox boundingBox;
                        leaf.GetBoundingBox(out boundingBox);
                        tree.SetLeafBoundingBox(i, ref boundingBox);
                    }
                    var refineStartTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;

                    int refinementCount;
                    if (looper.ThreadCount > 1)
                    {
                        refinementCount = tree.RefitAndRefine(t, looper, refineContext);
                    }
                    else
                    {
                        refinementCount = tree.RefitAndRefine(t);
                    }

                    var refineEndTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;

                    int overlapsCount;
                    if (looper.ThreadCount > 1)
                    {
                        tree.GetSelfOverlaps(looper, selfTestContext);
                        overlapsCount = 0;
                        for (int i = 0; i < selfTestContext.WorkerOverlaps.Length; ++i)
                        {
                            overlapsCount += selfTestContext.WorkerOverlaps[i].Count;
                        }
                    }
                    else
                    {
                        overlaps.Count = 0;
                        tree.GetSelfOverlapsArityDedicated(ref overlaps);
                        overlapsCount = overlaps.Count;
                    }

                    var testEndTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;

                    results.Refine[t]        = 1000 * (refineEndTime - refineStartTime);
                    results.SelfTest[t]      = 1000 * (testEndTime - refineEndTime);
                    results.Total[t]         = 1000 * (testEndTime - refineStartTime);
                    results.OverlapCounts[t] = overlapsCount;
                    results.TreeCosts[t]     = tree.MeasureCostMetric();

                    if (t % 16 == 0)
                    {
                        Console.WriteLine($"_________________{t}_________________");
                        Console.WriteLine($"Refinement count: {refinementCount}");
                        Console.WriteLine($"Refine time:      {results.Refine[t]}");
                        Console.WriteLine($"Test time:        {results.SelfTest[t]}");
                        Console.WriteLine($"TIME:             {results.Total[t]}");
                        Console.WriteLine($"Cost metric:      {results.TreeCosts[t]}");
                        Console.WriteLine($"Overlaps:         {results.OverlapCounts[t]}");
                        Console.WriteLine($"Cache Quality:    {tree.MeasureCacheQuality()}");
                        GC.Collect();
                    }
                    tree.Validate();
                }
                endTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                tree.Validate();
                Console.WriteLine($"SingleArray Cache Quality: {tree.MeasureCacheQuality()}");
                Console.WriteLine($"Cost metric: {tree.MeasureCostMetric()}");

                region.Dispose();
                tree.RemoveUnusedInternalNodes(ref spareNodes);
                BufferPools <int> .Thread.GiveBack(buffer);

                //********************

                tree.MeasureNodeOccupancy(out nodeCount, out childCount);
                Console.WriteLine($"SingleArray Occupancy: {childCount / (double)nodeCount}");

                startTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                for (int i = 0; i < refitCount; ++i)
                {
                    //for (int i = 0; i < tree.LeafCount; ++i)
                    //{
                    //    BoundingBox box;
                    //    leaves[tree.Leaves[i].Id].GetBoundingBox(out box);
                    //    tree.UpdateLeafBoundingBox(i, ref box);
                    //}
                    tree.Refit();
                }
                endTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                Console.WriteLine($"SingleArray Refit Time2: {endTime - startTime}");


                var list      = new QuickList <int>(new BufferPool <int>());
                var queryMask = queries.Length - 1;
                startTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                for (int i = 0; i < queryCount; ++i)
                {
                    list.Count = 0;
                    //tree.Query2(ref queries[i & queryMask], ref list);
                    tree.QueryRecursive(ref queries[i & queryMask], ref list);
                }
                endTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                Console.WriteLine($"SingleArray Query Time: {endTime - startTime}, overlaps: {list.Count}");
                Array.Clear(list.Elements, 0, list.Elements.Length);
                list.Dispose();

                startTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                for (int i = 0; i < selfTestCount; ++i)
                {
                    overlaps.Count = 0;
                    tree.GetSelfOverlaps(ref overlaps);
                }
                endTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                Console.WriteLine($"SingleArray SelfTree Time: {endTime - startTime}, overlaps: {overlaps.Count}");

                startTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                for (int i = 0; i < selfTestCount; ++i)
                {
                    overlaps.Count = 0;
                    tree.GetSelfOverlapsArityDedicated(ref overlaps);
                }
                endTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                Console.WriteLine($"SingleArray Arity-Dedicated SelfTree Time: {endTime - startTime}, overlaps: {overlaps.Count}");


                startTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                for (int i = 0; i < selfTestCount; ++i)
                {
                    overlaps.Count = 0;
                    tree.GetSelfOverlapsViaQueries(ref overlaps);
                }
                endTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                Console.WriteLine($"SingleArray SelfQuery Time: {endTime - startTime}, overlaps: {overlaps.Count}");

                tree.Dispose();

                return(results);
            }
        }
Esempio n. 2
0
        public static unsafe TestResults TestSingleArray(TestCollidable[] leaves, BoundingBox[] queries, BoundingBox positionBounds,
            int queryCount, int selfTestCount, int refitCount, int frameCount, float dt, ParallelLooper looper)
        {
            {

                var warmLeaves = GetLeaves(10, 10, 10, 10, 10);
                Tree tree = new Tree();
                //for (int i = 0; i < leaves.Length; ++i)
                //{
                //    BoundingBox box;
                //    leaves[i].GetBoundingBox(out box);
                //    //tree.Insert(i, ref box);
                //    tree.AddGlobal(i, ref box);
                //}
                int[] leafIds = new int[warmLeaves.Length];
                BoundingBox[] leafBounds = new BoundingBox[warmLeaves.Length];
                for (int i = 0; i < warmLeaves.Length; ++i)
                {
                    leafIds[i] = i;
                    warmLeaves[i].GetBoundingBox(out leafBounds[i]);
                }
                //tree.BuildMedianSplit(leafIds, leafBounds);
                //tree.BuildVolumeHeuristic(leafIds, leafBounds);
                tree.SweepBuild(leafIds, leafBounds);
                Console.WriteLine($"SingleArray Cachewarm Build: {tree.LeafCount}");

                tree.Refit();
                //tree.BottomUpAgglomerativeRefine();
                //tree.TopDownAgglomerativeRefine();
                //tree.BottomUpSweepRefine();
                //tree.TopDownSweepRefine();

                tree.RefitAndRefine(0);
                var context = new Tree.RefitAndRefineMultithreadedContext(tree);
                tree.RefitAndRefine(0, looper, context);

                var selfTestContext = new Tree.SelfTestMultithreadedContext(looper.ThreadCount, BufferPools<Overlap>.Locking);
                tree.GetSelfOverlaps(looper, selfTestContext);

                var list = new QuickList<int>(new BufferPool<int>());
                BoundingBox aabb = new BoundingBox { Min = new Vector3(0, 0, 0), Max = new Vector3(1, 1, 1) };
                tree.QueryRecursive(ref aabb, ref list);
                list.Dispose();

                var overlaps = new QuickList<Overlap>(new BufferPool<Overlap>());
                tree.GetSelfOverlaps(ref overlaps);

                overlaps = new QuickList<Overlap>(new BufferPool<Overlap>());
                tree.GetSelfOverlapsArityDedicated(ref overlaps);

                tree.IncrementalCacheOptimize(0);

                overlaps = new QuickList<Overlap>(new BufferPool<Overlap>());

                tree.GetSelfOverlapsViaQueries(ref overlaps);
                Console.WriteLine($"Cachewarm overlaps: {overlaps.Count}");
                tree.Dispose();

            }

            {
                Console.WriteLine($"SingleArray arity: {Tree.ChildrenCapacity}");
                Tree tree = new Tree(Math.Max(1, leaves.Length));
                var startTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                for (int i = 0; i < leaves.Length; ++i)
                {
                    var leafIndex = (int)((982451653L * i) % leaves.Length);
                    BoundingBox box;
                    leaves[leafIndex].GetBoundingBox(out box);
                    tree.Add(leafIndex, ref box);
                    //tree.AddGlobal(leafIndex, ref box);
                }
                //int[] leafIds = new int[leaves.Length];
                //BoundingBox[] leafBounds = new BoundingBox[leaves.Length];
                //for (int i = 0; i < leaves.Length; ++i)
                //{
                //    leafIds[i] = i;
                //    leaves[i].GetBoundingBox(out leafBounds[i]);
                //}
                ////tree.BuildMedianSplit(leafIds, leafBounds);
                ////tree.BuildVolumeHeuristic(leafIds, leafBounds);
                //tree.SweepBuild(leafIds, leafBounds);
                var endTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                Console.WriteLine($"SingleArray Build Time: {endTime - startTime}, depth: {tree.ComputeMaximumDepth()}");

                int nodeCount, childCount;
                tree.MeasureNodeOccupancy(out nodeCount, out childCount);
                Console.WriteLine($"SingleArray Occupancy: {childCount / (double)nodeCount}");
                Console.WriteLine($"Cost metric: {tree.MeasureCostMetric()}");
                Console.WriteLine($"Cache Quality: {tree.MeasureCacheQuality()}");

                tree.Validate();

                startTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                for (int i = 0; i < refitCount; ++i)
                {
                    //for (int i = 0; i < tree.LeafCount; ++i)
                    //{
                    //    BoundingBox box;
                    //    leaves[tree.Leaves[i].Id].GetBoundingBox(out box);
                    //    tree.UpdateLeafBoundingBox(i, ref box);
                    //}
                    tree.Refit();
                }
                endTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                Console.WriteLine($"SingleArray Refit Time1: {endTime - startTime}");

                var overlaps = new QuickList<Overlap>(new BufferPool<Overlap>());
                startTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                for (int i = 0; i < selfTestCount; ++i)
                {
                    overlaps.Count = 0;
                    tree.GetSelfOverlaps(ref overlaps);
                }
                endTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                Console.WriteLine($"SingleArray SelfTree Time1: {endTime - startTime}, overlaps: {overlaps.Count}");

                int[] buffer;
                MemoryRegion region;
                BinnedResources resources;
                const int maximumSubtrees = 262144;
                var spareNodes = new QuickList<int>(new BufferPool<int>(), 8);
                var subtreeReferences = new QuickList<int>(BufferPools<int>.Thread, BufferPool<int>.GetPoolIndex(maximumSubtrees));
                var treeletInternalNodes = new QuickList<int>(BufferPools<int>.Thread, BufferPool<int>.GetPoolIndex(maximumSubtrees));
                Tree.CreateBinnedResources(BufferPools<int>.Thread, maximumSubtrees, out buffer, out region, out resources);
                bool nodesInvalidated;
                overlaps = new QuickList<Overlap>(new BufferPool<Overlap>());

                var refineContext = new Tree.RefitAndRefineMultithreadedContext(tree);
                var selfTestContext = new Tree.SelfTestMultithreadedContext(looper.ThreadCount, BufferPools<Overlap>.Locking);

                var visitedNodes = new QuickSet<int>(BufferPools<int>.Thread, BufferPools<int>.Thread);

                //**************** Dynamic Testing
                Random random = new Random(5);
                TestResults results = new TestResults("New", frameCount);
                startTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                for (int t = 0; t < frameCount; ++t)
                {
                    //Update the positions of objects.
                    for (int i = 0; i < tree.LeafCount; ++i)
                    {
                        var leafId = tree.Leaves[i].Id;
                        var leaf = leaves[leafId];

                        //Bounce off the walls.
                        if (leaf.Position.X < positionBounds.Min.X && leaf.Velocity.X < 0)
                            leaf.Velocity.X = -leaf.Velocity.X;
                        if (leaf.Position.Y < positionBounds.Min.Y && leaf.Velocity.Y < 0)
                            leaf.Velocity.Y = -leaf.Velocity.Y;
                        if (leaf.Position.Z < positionBounds.Min.Z && leaf.Velocity.Z < 0)
                            leaf.Velocity.Z = -leaf.Velocity.Z;

                        if (leaf.Position.X > positionBounds.Max.X && leaf.Velocity.X > 0)
                            leaf.Velocity.X = -leaf.Velocity.X;
                        if (leaf.Position.Y > positionBounds.Max.Y && leaf.Velocity.Y > 0)
                            leaf.Velocity.Y = -leaf.Velocity.Y;
                        if (leaf.Position.Z > positionBounds.Max.Z && leaf.Velocity.Z > 0)
                            leaf.Velocity.Z = -leaf.Velocity.Z;

                        leaf.Position += leaf.Velocity * dt;
                        BoundingBox boundingBox;
                        leaf.GetBoundingBox(out boundingBox);
                        tree.SetLeafBoundingBox(i, ref boundingBox);
                    }
                    var refineStartTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;

                    int refinementCount;
                    if(looper.ThreadCount > 1)
                        refinementCount = tree.RefitAndRefine(t, looper, refineContext);
                    else
                        refinementCount = tree.RefitAndRefine(t);

                    var refineEndTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;

                    int overlapsCount;
                    if (looper.ThreadCount > 1)
                    {
                        tree.GetSelfOverlaps(looper, selfTestContext);
                        overlapsCount = 0;
                        for (int i = 0; i < selfTestContext.WorkerOverlaps.Length; ++i)
                        {
                            overlapsCount += selfTestContext.WorkerOverlaps[i].Count;
                        }
                    }
                    else
                    {
                        overlaps.Count = 0;
                        tree.GetSelfOverlapsArityDedicated(ref overlaps);
                        overlapsCount = overlaps.Count;
                    }

                    var testEndTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;

                    results.Refine[t] = 1000 * (refineEndTime - refineStartTime);
                    results.SelfTest[t] = 1000 * (testEndTime - refineEndTime);
                    results.Total[t] = 1000 * (testEndTime - refineStartTime);
                    results.OverlapCounts[t] = overlapsCount;
                    results.TreeCosts[t] = tree.MeasureCostMetric();

                    if (t % 16 == 0)
                    {
                        Console.WriteLine($"_________________{t}_________________");
                        Console.WriteLine($"Refinement count: {refinementCount}");
                        Console.WriteLine($"Refine time:      {results.Refine[t]}");
                        Console.WriteLine($"Test time:        {results.SelfTest[t]}");
                        Console.WriteLine($"TIME:             {results.Total[t]}");
                        Console.WriteLine($"Cost metric:      {results.TreeCosts[t]}");
                        Console.WriteLine($"Overlaps:         {results.OverlapCounts[t]}");
                        Console.WriteLine($"Cache Quality:    {tree.MeasureCacheQuality()}");
                        GC.Collect();
                    }
                    tree.Validate();
                }
                endTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                tree.Validate();
                Console.WriteLine($"SingleArray Cache Quality: {tree.MeasureCacheQuality()}");
                Console.WriteLine($"Cost metric: {tree.MeasureCostMetric()}");

                region.Dispose();
                tree.RemoveUnusedInternalNodes(ref spareNodes);
                BufferPools<int>.Thread.GiveBack(buffer);

                //********************

                tree.MeasureNodeOccupancy(out nodeCount, out childCount);
                Console.WriteLine($"SingleArray Occupancy: {childCount / (double)nodeCount}");

                startTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                for (int i = 0; i < refitCount; ++i)
                {
                    //for (int i = 0; i < tree.LeafCount; ++i)
                    //{
                    //    BoundingBox box;
                    //    leaves[tree.Leaves[i].Id].GetBoundingBox(out box);
                    //    tree.UpdateLeafBoundingBox(i, ref box);
                    //}
                    tree.Refit();
                }
                endTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                Console.WriteLine($"SingleArray Refit Time2: {endTime - startTime}");

                var list = new QuickList<int>(new BufferPool<int>());
                var queryMask = queries.Length - 1;
                startTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                for (int i = 0; i < queryCount; ++i)
                {
                    list.Count = 0;
                    //tree.Query2(ref queries[i & queryMask], ref list);
                    tree.QueryRecursive(ref queries[i & queryMask], ref list);
                }
                endTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                Console.WriteLine($"SingleArray Query Time: {endTime - startTime}, overlaps: {list.Count}");
                Array.Clear(list.Elements, 0, list.Elements.Length);
                list.Dispose();

                startTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                for (int i = 0; i < selfTestCount; ++i)
                {
                    overlaps.Count = 0;
                    tree.GetSelfOverlaps(ref overlaps);
                }
                endTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                Console.WriteLine($"SingleArray SelfTree Time: {endTime - startTime}, overlaps: {overlaps.Count}");

                startTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                for (int i = 0; i < selfTestCount; ++i)
                {
                    overlaps.Count = 0;
                    tree.GetSelfOverlapsArityDedicated(ref overlaps);
                }
                endTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                Console.WriteLine($"SingleArray Arity-Dedicated SelfTree Time: {endTime - startTime}, overlaps: {overlaps.Count}");

                startTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                for (int i = 0; i < selfTestCount; ++i)
                {
                    overlaps.Count = 0;
                    tree.GetSelfOverlapsViaQueries(ref overlaps);
                }
                endTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                Console.WriteLine($"SingleArray SelfQuery Time: {endTime - startTime}, overlaps: {overlaps.Count}");

                tree.Dispose();

                return results;
            }
        }
Esempio n. 3
0
        public static TestResults TestDH(TestCollidableBEPU[] leaves, BEPUutilities.BoundingBox[] queries, ref BoundingBox positionBounds,
            int queryCount, int selfTestCount, int refitCount, int frameCount, float dt, IParallelLooper looper)
        {
            GC.Collect();
            {

                DynamicHierarchy tree = new DynamicHierarchy(looper);
                for (int i = 0; i < leaves.Length; ++i)
                {
                    tree.Add(leaves[i]);
                }

                if (looper.ThreadCount > 1)
                    tree.MultithreadedRefitPhase(tree.GetSplitDepth());
                else
                    tree.SingleThreadedRefitPhase();

                tree.Overlaps.Count = 0;
                if (looper.ThreadCount > 1)
                    tree.MultithreadedOverlapPhase(tree.GetSplitDepth());
                else
                    tree.SingleThreadedOverlapPhase();

                for (int i = 0; i < leaves.Length; ++i)
                {
                    tree.Remove(leaves[i]);
                }

            }
            GC.Collect();

            {

                var startTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                DynamicHierarchy tree = new DynamicHierarchy(looper);
                for (int i = 0; i < leaves.Length; ++i)
                {
                    tree.Add(leaves[i]);
                }

                var endTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                Console.WriteLine($"DH Build Time: {endTime - startTime}");
                Console.WriteLine($"Cost metric: {tree.MeasureCostMetric()}");

                //tree.SingleThreadedRefitPhase();
                //startTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                //for (int i = 0; i < refitCount; ++i)
                //{
                //    tree.SingleThreadedRefitPhase();
                //    //Console.WriteLine($"Cost metric: {tree.MeasureCostMetric()}");
                //}
                //endTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                //Console.WriteLine($"DH Refit Time: {endTime - startTime}");
                //Console.WriteLine($"Cost metric: {tree.MeasureCostMetric()}");

                //tree.SingleThreadedOverlapPhase();
                //startTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                //for (int i = 0; i < selfTestCount; ++i)
                //{
                //    tree.Overlaps.Clear();
                //    tree.SingleThreadedOverlapPhase();
                //}
                //endTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                //Console.WriteLine($"DH selftest Time: {endTime - startTime}, overlaps: {tree.Overlaps.Count}");

                //**************** Dynamic Testing
                Random random = new Random(5);
                TestResults results = new TestResults("Old", frameCount);

                startTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                for (int t = 0; t < frameCount; ++t)
                {
                    //Update the positions of objects.
                    for (int i = 0; i < leaves.Length; ++i)
                    {
                        var leaf = leaves[i];

                        //Bounce off the walls.
                        if (leaf.Position.X < positionBounds.Min.X && leaf.Velocity.X < 0)
                            leaf.Velocity.X = -leaf.Velocity.X;
                        if (leaf.Position.Y < positionBounds.Min.Y && leaf.Velocity.Y < 0)
                            leaf.Velocity.Y = -leaf.Velocity.Y;
                        if (leaf.Position.Z < positionBounds.Min.Z && leaf.Velocity.Z < 0)
                            leaf.Velocity.Z = -leaf.Velocity.Z;

                        if (leaf.Position.X > positionBounds.Max.X && leaf.Velocity.X > 0)
                            leaf.Velocity.X = -leaf.Velocity.X;
                        if (leaf.Position.Y > positionBounds.Max.Y && leaf.Velocity.Y > 0)
                            leaf.Velocity.Y = -leaf.Velocity.Y;
                        if (leaf.Position.Z > positionBounds.Max.Z && leaf.Velocity.Z > 0)
                            leaf.Velocity.Z = -leaf.Velocity.Z;

                        leaf.Position += leaf.Velocity * dt;
                        leaf.UpdateBoundingBox();
                    }
                    var refineStartTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;

                    if (looper.ThreadCount > 1)
                        tree.MultithreadedRefitPhase(tree.GetSplitDepth());
                    else
                        tree.SingleThreadedRefitPhase();

                    //tree.Refit();
                    //for (int i = 0; i < 1; ++i)
                    //{

                    //    subtreeReferences.Count = 0;
                    //    treeletInternalNodes.Count = 0;
                    //    tree.BinnedRefine(0, ref subtreeReferences, maximumSubtrees, ref treeletInternalNodes, ref spareNodes, ref resources, out nodesInvalidated);
                    //}
                    //tree.RemoveUnusedInternalNodes(ref spareNodes);

                    var refineEndTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;

                    tree.Overlaps.Count = 0;
                    if (looper.ThreadCount > 1)
                        tree.MultithreadedOverlapPhase(tree.GetSplitDepth());
                    else
                        tree.SingleThreadedOverlapPhase();

                    var testEndTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;

                    results.Refine[t] = 1000 * (refineEndTime - refineStartTime);
                    results.SelfTest[t] = 1000 * (testEndTime - refineEndTime);
                    results.Total[t] = 1000 * (testEndTime - refineStartTime);
                    results.OverlapCounts[t] = tree.Overlaps.Count;
                    results.TreeCosts[t] = tree.MeasureCostMetric();

                    if (t % 16 == 0)
                    {
                        Console.WriteLine($"_________________{t}_________________");
                        Console.WriteLine($"Refine time:      {results.Refine[t]}");
                        Console.WriteLine($"Test time:        {results.SelfTest[t]}");
                        Console.WriteLine($"TIME:             {results.Total[t]}");
                        Console.WriteLine($"Cost metric:      {results.TreeCosts[t]}");
                        Console.WriteLine($"Overlaps:         {results.OverlapCounts[t]}");
                        GC.Collect();
                    }
                }
                endTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                Console.WriteLine($"Cost metric: {tree.MeasureCostMetric()}");

                tree.Overlaps.Clear();
                tree.SingleThreadedOverlapPhase();
                startTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                for (int i = 0; i < selfTestCount; ++i)
                {
                    tree.Overlaps.Clear();
                    tree.SingleThreadedOverlapPhase();
                }
                endTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                Console.WriteLine($"DH selftest Time2: {endTime - startTime}, overlaps: {tree.Overlaps.Count}");

                return results;
            }
        }
Esempio n. 4
0
        public static TestResults TestDH(TestCollidableBEPU[] leaves, BEPUutilities.BoundingBox[] queries, ref BoundingBox positionBounds,
                                         int queryCount, int selfTestCount, int refitCount, int frameCount, float dt, IParallelLooper looper)
        {
            GC.Collect();
            {
                DynamicHierarchy tree = new DynamicHierarchy(looper);
                for (int i = 0; i < leaves.Length; ++i)
                {
                    tree.Add(leaves[i]);
                }

                if (looper.ThreadCount > 1)
                {
                    tree.MultithreadedRefitPhase(tree.GetSplitDepth());
                }
                else
                {
                    tree.SingleThreadedRefitPhase();
                }

                tree.Overlaps.Count = 0;
                if (looper.ThreadCount > 1)
                {
                    tree.MultithreadedOverlapPhase(tree.GetSplitDepth());
                }
                else
                {
                    tree.SingleThreadedOverlapPhase();
                }

                for (int i = 0; i < leaves.Length; ++i)
                {
                    tree.Remove(leaves[i]);
                }
            }
            GC.Collect();

            {
                var startTime         = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                DynamicHierarchy tree = new DynamicHierarchy(looper);
                for (int i = 0; i < leaves.Length; ++i)
                {
                    tree.Add(leaves[i]);
                }

                var endTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                Console.WriteLine($"DH Build Time: {endTime - startTime}");
                Console.WriteLine($"Cost metric: {tree.MeasureCostMetric()}");

                //tree.SingleThreadedRefitPhase();
                //startTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                //for (int i = 0; i < refitCount; ++i)
                //{
                //    tree.SingleThreadedRefitPhase();
                //    //Console.WriteLine($"Cost metric: {tree.MeasureCostMetric()}");
                //}
                //endTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                //Console.WriteLine($"DH Refit Time: {endTime - startTime}");
                //Console.WriteLine($"Cost metric: {tree.MeasureCostMetric()}");

                //tree.SingleThreadedOverlapPhase();
                //startTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                //for (int i = 0; i < selfTestCount; ++i)
                //{
                //    tree.Overlaps.Clear();
                //    tree.SingleThreadedOverlapPhase();
                //}
                //endTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                //Console.WriteLine($"DH selftest Time: {endTime - startTime}, overlaps: {tree.Overlaps.Count}");


                //**************** Dynamic Testing
                Random      random  = new Random(5);
                TestResults results = new TestResults("Old", frameCount);

                startTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                for (int t = 0; t < frameCount; ++t)
                {
                    //Update the positions of objects.
                    for (int i = 0; i < leaves.Length; ++i)
                    {
                        var leaf = leaves[i];

                        //Bounce off the walls.
                        if (leaf.Position.X < positionBounds.Min.X && leaf.Velocity.X < 0)
                        {
                            leaf.Velocity.X = -leaf.Velocity.X;
                        }
                        if (leaf.Position.Y < positionBounds.Min.Y && leaf.Velocity.Y < 0)
                        {
                            leaf.Velocity.Y = -leaf.Velocity.Y;
                        }
                        if (leaf.Position.Z < positionBounds.Min.Z && leaf.Velocity.Z < 0)
                        {
                            leaf.Velocity.Z = -leaf.Velocity.Z;
                        }

                        if (leaf.Position.X > positionBounds.Max.X && leaf.Velocity.X > 0)
                        {
                            leaf.Velocity.X = -leaf.Velocity.X;
                        }
                        if (leaf.Position.Y > positionBounds.Max.Y && leaf.Velocity.Y > 0)
                        {
                            leaf.Velocity.Y = -leaf.Velocity.Y;
                        }
                        if (leaf.Position.Z > positionBounds.Max.Z && leaf.Velocity.Z > 0)
                        {
                            leaf.Velocity.Z = -leaf.Velocity.Z;
                        }

                        leaf.Position += leaf.Velocity * dt;
                        leaf.UpdateBoundingBox();
                    }
                    var refineStartTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;

                    if (looper.ThreadCount > 1)
                    {
                        tree.MultithreadedRefitPhase(tree.GetSplitDepth());
                    }
                    else
                    {
                        tree.SingleThreadedRefitPhase();
                    }


                    //tree.Refit();
                    //for (int i = 0; i < 1; ++i)
                    //{

                    //    subtreeReferences.Count = 0;
                    //    treeletInternalNodes.Count = 0;
                    //    tree.BinnedRefine(0, ref subtreeReferences, maximumSubtrees, ref treeletInternalNodes, ref spareNodes, ref resources, out nodesInvalidated);
                    //}
                    //tree.RemoveUnusedInternalNodes(ref spareNodes);

                    var refineEndTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;

                    tree.Overlaps.Count = 0;
                    if (looper.ThreadCount > 1)
                    {
                        tree.MultithreadedOverlapPhase(tree.GetSplitDepth());
                    }
                    else
                    {
                        tree.SingleThreadedOverlapPhase();
                    }

                    var testEndTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;

                    results.Refine[t]        = 1000 * (refineEndTime - refineStartTime);
                    results.SelfTest[t]      = 1000 * (testEndTime - refineEndTime);
                    results.Total[t]         = 1000 * (testEndTime - refineStartTime);
                    results.OverlapCounts[t] = tree.Overlaps.Count;
                    results.TreeCosts[t]     = tree.MeasureCostMetric();

                    if (t % 16 == 0)
                    {
                        Console.WriteLine($"_________________{t}_________________");
                        Console.WriteLine($"Refine time:      {results.Refine[t]}");
                        Console.WriteLine($"Test time:        {results.SelfTest[t]}");
                        Console.WriteLine($"TIME:             {results.Total[t]}");
                        Console.WriteLine($"Cost metric:      {results.TreeCosts[t]}");
                        Console.WriteLine($"Overlaps:         {results.OverlapCounts[t]}");
                        GC.Collect();
                    }
                }
                endTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                Console.WriteLine($"Cost metric: {tree.MeasureCostMetric()}");

                tree.Overlaps.Clear();
                tree.SingleThreadedOverlapPhase();
                startTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                for (int i = 0; i < selfTestCount; ++i)
                {
                    tree.Overlaps.Clear();
                    tree.SingleThreadedOverlapPhase();
                }
                endTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                Console.WriteLine($"DH selftest Time2: {endTime - startTime}, overlaps: {tree.Overlaps.Count}");

                return(results);
            }
        }