Пример #1
0
        // ******************************************************************
        /// <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);
            }
        }
Пример #2
0
        // ******************************************************************
        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);
        }