// ****************************************************************** /// <summary> /// /// </summary> /// <param name="threadUsage">Using ConvexHullThreadUsage.All will only use all thread for the first pass (se quadrant limits) then use only 4 threads for pass 2 (which is the actual limit).</param> public void CalcConvexHull(ConvexHullThreadUsage threadUsage = ConvexHullThreadUsage.OneOrFour) { if (IsZeroData()) { return; } if (threadUsage == ConvexHullThreadUsage.AutoSelect || threadUsage == ConvexHullThreadUsage.OneOrFour) { if (Environment.ProcessorCount == 1) { threadUsage = ConvexHullThreadUsage.OnlyOne; } // It's around 10 000 000 points on a 12 cores that some advantages really start to appear else if (threadUsage == ConvexHullThreadUsage.OneOrFour || Environment.ProcessorCount <= 4 || _listOfPoint.Count < 10000000) { threadUsage = ConvexHullThreadUsage.FixedFour; } else { threadUsage = ConvexHullThreadUsage.All; } } // There is no need to start more than 1 thread. It will not be usefull on a single core machine. if (threadUsage == ConvexHullThreadUsage.OnlyOne) { SetQuadrantLimitsOneThread(); _q1.Calc(true); _q2.Calc(true); _q3.Calc(true); _q4.Calc(true); } else { bool isSkipSetQuadrantLimit = false; if (threadUsage == ConvexHullThreadUsage.All) { isSkipSetQuadrantLimit = true; SetQuadrantLimitsUsingAllThreads(); } Quadrant[] quadrants = new Quadrant[4]; quadrants[0] = _q1; quadrants[1] = _q2; quadrants[2] = _q3; quadrants[3] = _q4; Task[] tasks = new Task[4]; for (int n = 0; n < tasks.Length; n++) { int nLocal = n; // Prevent Lambda internal closure error. tasks[n] = Task.Factory.StartNew(() => quadrants[nLocal].Calc(isSkipSetQuadrantLimit)); } Task.WaitAll(tasks); } }
// ****************************************************************** private void Init(IReadOnlyList <Point> listOfPoint, bool shouldCloseTheGraph, int initialResultGuessSize) { _listOfPoint = listOfPoint; _shouldCloseTheGraph = shouldCloseTheGraph; if (initialResultGuessSize <= 0 && !IsZeroData()) { initialResultGuessSize = Math.Min((int)Math.Sqrt(listOfPoint.Count), 100); } if (_pointArrayManipulationType == PointArrayManipulationType.ArrayCopyImmutable) { initialResultGuessSize = 0; } _q1 = new QuadrantSpecific1(_listOfPoint, initialResultGuessSize); _q2 = new QuadrantSpecific2(_listOfPoint, initialResultGuessSize); _q3 = new QuadrantSpecific3(_listOfPoint, initialResultGuessSize); _q4 = new QuadrantSpecific4(_listOfPoint, initialResultGuessSize); }