// ****************************************************************** /// <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 || this.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) { _q1.Calc(); _q2.Calc(); _q3.Calc(); _q4.Calc(); } else { bool isSkipSetQuadrantLimit = false; if (threadUsage == ConvexHullThreadUsage.All) { isSkipSetQuadrantLimit = true; SetQuadrantLimitsUsingAllThreads(); } Quadrant <T>[] quadrants = new Quadrant <T> [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(IEnumerable <IEnumerable <T> > listOfListOfPoint, bool shouldCloseTheGraph, int initialResultGuessSize) { _listOfListOfPoint = listOfListOfPoint; _shouldCloseTheGraph = shouldCloseTheGraph; if (initialResultGuessSize <= 0 && !IsZeroData()) { int totalPointCount = 0; foreach (var enumOfPoint in listOfListOfPoint) { totalPointCount += enumOfPoint.Count(); } initialResultGuessSize = Math.Min((int)Math.Sqrt(totalPointCount), 100); } _q1 = new QuadrantSpecific1 <T>(listOfListOfPoint, initialResultGuessSize, _xGet, _yGet, _pointConstructor, _pointEqual); _q2 = new QuadrantSpecific2 <T>(listOfListOfPoint, initialResultGuessSize, _xGet, _yGet, _pointConstructor, _pointEqual); _q3 = new QuadrantSpecific3 <T>(listOfListOfPoint, initialResultGuessSize, _xGet, _yGet, _pointConstructor, _pointEqual); _q4 = new QuadrantSpecific4 <T>(listOfListOfPoint, initialResultGuessSize, _xGet, _yGet, _pointConstructor, _pointEqual); }