Esempio n. 1
0
        private Measurement MultiInvoke <T>(IterationMode mode, int index, Action setupAction, Func <T> targetAction, Action cleanupAction, long invocationCount, long operationsPerInvoke, GarbageCollection garbageCollectionSettings, T returnHolder = default(T))
        {
            var totalOperations = invocationCount * operationsPerInvoke;

            setupAction();
            ClockSpan clockSpan;

            GcCollect(garbageCollectionSettings);
            if (invocationCount == 1)
            {
                var chronometer = Chronometer.Start();
                returnHolder = targetAction();
                clockSpan    = chronometer.Stop();
            }
            else if (invocationCount < int.MaxValue)
            {
                int intInvocationCount = (int)invocationCount;
                var chronometer        = Chronometer.Start();
                RunAction(targetAction, intInvocationCount);
                clockSpan = chronometer.Stop();
            }
            else
            {
                var chronometer = Chronometer.Start();
                RunAction(targetAction, invocationCount);
                clockSpan = chronometer.Stop();
            }
            multiInvokeReturnHolder = returnHolder;
            var measurement = new Measurement(0, mode, index, totalOperations, clockSpan.GetNanoseconds());

            Console.WriteLine(measurement.ToOutputLine());
            GcCollect(garbageCollectionSettings);
            return(measurement);
        }
Esempio n. 2
0
    public void Update()
    {
        //switch iteration mode
        if (Input.GetKeyDown(KeyCode.LeftBracket))
        {
            selectedAlgorithm = ((int)selectedAlgorithm) == aMin ? (Algorithm)aMax : (Algorithm)(selectedAlgorithm - 1);
            TempText.setTempText($"Selected algorithm: {selectedAlgorithm.ToString()}", 3);
        }
        if (Input.GetKeyDown(KeyCode.RightBracket))
        {
            selectedAlgorithm = ((int)selectedAlgorithm) == aMax ? (Algorithm)aMin : (Algorithm)(selectedAlgorithm + 1);
            TempText.setTempText($"Selected algorithm: {selectedAlgorithm.ToString()}", 3);
        }

        if (Input.GetKeyDown(KeyCode.Semicolon))
        {
            iterationMode = ((int)iterationMode) == iMin ? (IterationMode)iMax : (IterationMode)(iterationMode - 1);
            TempText.setTempText($"Selected iteration mode: {iterationMode.ToString()}", 3);
        }
        if (Input.GetKeyDown(KeyCode.Quote))
        {
            iterationMode = ((int)iterationMode) == iMax ? (IterationMode)iMin : (IterationMode)(iterationMode + 1);
            TempText.setTempText($"Selected iteration mode: {iterationMode.ToString()}", 3);
        }
    }
Esempio n. 3
0
        private List <Measurement> RunAuto(long invokeCount, IterationMode iterationMode, int unrollFactor)
        {
            var    measurements     = new List <Measurement>();
            int    iterationCounter = 0;
            bool   isIdle           = iterationMode.IsIdle();
            double maxErrorRelative = isIdle ? MaxIdleStdErrRelative : Resolver.Resolve(TargetAccuracy.MaxStdErrRelative);

            while (true)
            {
                iterationCounter++;
                var measurement = RunIteration(iterationMode, iterationCounter, invokeCount, unrollFactor);
                measurements.Add(measurement);

                var statistics = new Statistics(measurements.Select(m => m.Nanoseconds));
                if (Resolver.Resolve(TargetAccuracy.RemoveOutliers))
                {
                    statistics = new Statistics(statistics.WithoutOutliers());
                }
                double actualError = statistics.StandardError;
                double maxError    = maxErrorRelative * statistics.Mean;

                if (iterationCounter >= MinIterationCount && actualError < maxError)
                {
                    break;
                }

                if (iterationCounter >= MaxIterationCount || (isIdle && iterationCounter >= MaxIdleIterationCount))
                {
                    break;
                }
            }
            WriteLine();
            return(measurements);
        }
Esempio n. 4
0
        public override string ToString()
        {
            var builder = new StringBuilder();

            builder.Append((IterationMode.ToString() + IterationStage).PadRight(IterationInfoNameMaxWidth, ' '));
            builder.Append(' ');

            // Usually, a benchmarks takes more than 10 iterations (rarely more than 99)
            // PadLeft(2, ' ') looks like a good trade-off between alignment and amount of characters
            builder.Append(IterationIndex.ToString(MainCultureInfo).PadLeft(2, ' '));
            builder.Append(": ");

            builder.Append(Operations.ToString(MainCultureInfo));
            builder.Append(' ');
            builder.Append(OpSymbol);
            builder.Append(", ");

            builder.Append(Nanoseconds.ToString("0.00", MainCultureInfo));
            builder.Append(' ');
            builder.Append(NsSymbol);
            builder.Append(", ");

            builder.Append(GetAverageTime().ToString(MainCultureInfo).ToAscii());
            builder.Append("/op");

            return(builder.ToString());
        }
Esempio n. 5
0
        private bool IsWarmupFinished(List <Measurement> measurements, IterationMode iterationMode)
        {
            int n = measurements.Count;

            if (n >= maxIterationCount || iterationMode == IterationMode.Overhead && n >= MaxOverheadIterationCount)
            {
                return(true);
            }
            if (n < minIterationCount)
            {
                return(false);
            }

            int dir = -1, changeCount = 0;

            for (int i = 1; i < n; i++)
            {
                int nextDir = Math.Sign(measurements[i].Nanoseconds - measurements[i - 1].Nanoseconds);
                if (nextDir != dir || nextDir == 0)
                {
                    dir = nextDir;
                    changeCount++;
                }
            }

            return(changeCount >= 4);
        }
Esempio n. 6
0
 public IterationData(IterationMode iterationMode, int index, long invokeCount, int unrollFactor)
 {
     IterationMode = iterationMode;
     Index         = index;
     InvokeCount   = invokeCount;
     UnrollFactor  = unrollFactor;
 }
        private Measurement MultiInvoke(
            IterationMode mode, int index, Action setupAction, Action targetAction, long invocationCount,
            long operationsPerInvoke)
        {
            var totalOperations = invocationCount * operationsPerInvoke;

            setupAction();
            ClockSpan clockSpan;

            GcCollect();
            if (invocationCount == 1)
            {
                var chronometer = Chronometer.Start();
                targetAction();
                clockSpan = chronometer.Stop();
            }
            else if (invocationCount < int.MaxValue)
            {
                int intInvocationCount = (int)invocationCount;
                var chronometer        = Chronometer.Start();
                RunAction(targetAction, intInvocationCount);
                clockSpan = chronometer.Stop();
            }
            else
            {
                var chronometer = Chronometer.Start();
                RunAction(targetAction, invocationCount);
                clockSpan = chronometer.Stop();
            }
            var measurement = new Measurement(0, mode, index, totalOperations, clockSpan.GetNanoseconds());

            Console.WriteLine(measurement.ToOutputLine());
            GcCollect();
            return(measurement);
        }
Esempio n. 8
0
        public IEnumerable <T> GetItemEnumerable(IterationMode mode           = IterationMode.Linear,
                                                 IterationDirection direction = IterationDirection.Forward)
        {
            switch (mode)
            {
            case IterationMode.Linear:
                foreach (var node in LinearEnumerable(direction))
                {
                    yield return(node.Value);
                }

                yield break;

            case IterationMode.Circular:
                foreach (var node in CircularEnumerable(direction))
                {
                    yield return(node.Value);
                }

                yield break;

            case IterationMode.Harmonic:
                foreach (var node in HarmonicEnumerable(direction))
                {
                    yield return(node.Value);
                }

                yield break;

            default:
                yield break;
            }
        }
 public IterationData(IterationMode iterationMode, int index, long invokeCount, int unrollFactor)
 {
     IterationMode = iterationMode;
     Index = index;
     InvokeCount = invokeCount;
     UnrollFactor = unrollFactor;
 }
        private static bool IsWarmupFinished(List <Measurement> measurements, IterationMode iterationMode)
        {
            int n = measurements.Count;

            if (n >= MaxIterationCount || (iterationMode.IsIdle() && n >= MaxIdleItertaionCount))
            {
                return(true);
            }
            if (n < MinIterationCount)
            {
                return(false);
            }

            int dir = -1, changeCount = 0;

            for (int i = 1; i < n; i++)
            {
                int nextDir = Math.Sign(measurements[i].Nanoseconds - measurements[i - 1].Nanoseconds);
                if (nextDir != dir || nextDir == 0)
                {
                    dir = nextDir;
                    changeCount++;
                }
            }

            return(changeCount >= 4);
        }
        private List<Measurement> RunAuto(long invokeCount, IterationMode iterationMode, int unrollFactor)
        {
            var measurements = new List<Measurement>(MaxIterationCount);
            var measurementsForStatistics = new List<Measurement>(MaxIterationCount);

            int iterationCounter = 0;
            bool isIdle = iterationMode.IsIdle();
            double maxErrorRelative = isIdle ? MaxIdleStdErrRelative : maxStdErrRelative;
            while (true)
            {
                iterationCounter++;
                var measurement = RunIteration(iterationMode, iterationCounter, invokeCount, unrollFactor);
                measurements.Add(measurement);
                measurementsForStatistics.Add(measurement);

                var statistics = MeasurementsStatistics.Calculate(measurementsForStatistics, removeOutliers);
                double actualError = statistics.StandardError;
                double maxError = maxErrorRelative * statistics.Mean;

                if (iterationCounter >= MinIterationCount && actualError < maxError)
                    break;

                if (iterationCounter >= MaxIterationCount || (isIdle && iterationCounter >= MaxIdleIterationCount))
                    break;
            }
            if (!IsDiagnoserAttached) WriteLine();
            return measurements;
        }
        private List <Measurement> RunAuto(long invokeCount, IterationMode iterationMode, int unrollFactor)
        {
            int    iterationCounter = 0;
            bool   isIdle           = iterationMode.IsIdle();
            double maxErrorRelative = isIdle ? MaxIdleStdErrRelative : maxStdErrRelative;

            while (true)
            {
                iterationCounter++;
                var measurement = RunIteration(iterationMode, iterationCounter, invokeCount, unrollFactor);
                measurements.Add(measurement);

                var    statistics  = MeasurementsStatistics.Calculate(measurements, removeOutliers);
                double actualError = statistics.StandardError;
                double maxError    = maxErrorRelative * statistics.Mean;

                if (iterationCounter >= MinIterationCount && actualError < maxError)
                {
                    break;
                }

                if (iterationCounter >= MaxIterationCount || (isIdle && iterationCounter >= MaxIdleIterationCount))
                {
                    break;
                }
            }
            if (!IsDiagnoserAttached)
            {
                WriteLine();
            }
            return(measurements);
        }
Esempio n. 13
0
 protected Measurement RunIteration(IterationMode mode, int index, long invokeCount, int unrollFactor)
 {
     if (invokeCount % unrollFactor != 0)
     {
         throw new ArgumentOutOfRangeException($"InvokeCount({invokeCount}) should be a multiple of UnrollFactor({unrollFactor}).");
     }
     return(engine.RunIteration(new IterationData(mode, index, invokeCount, unrollFactor)));
 }
Esempio n. 14
0
 /// <summary>
 /// Creates an instance of <see cref="Measurement"/> class.
 /// </summary>
 /// <param name="launchIndex"></param>
 /// <param name="iterationMode"></param>
 /// <param name="iterationIndex"></param>
 /// <param name="operations">The number of operations performed.</param>
 /// <param name="nanoseconds">The total number of nanoseconds it took to perform all operations.</param>
 public Measurement(int launchIndex, IterationMode iterationMode, int iterationIndex, long operations, double nanoseconds)
 {
     IterationMode = iterationMode;
     IterationIndex = iterationIndex;
     Operations = operations;
     Nanoseconds = nanoseconds;
     LaunchIndex = launchIndex;
 }
Esempio n. 15
0
 /// <summary>
 /// Creates an instance of <see cref="Measurement"/> class.
 /// </summary>
 /// <param name="launchIndex"></param>
 /// <param name="iterationMode"></param>
 /// <param name="iterationIndex"></param>
 /// <param name="operations">The number of operations performed.</param>
 /// <param name="nanoseconds">The total number of nanoseconds it took to perform all operations.</param>
 public Measurement(int launchIndex, IterationMode iterationMode, int iterationIndex, long operations, double nanoseconds)
 {
     IterationMode  = iterationMode;
     IterationIndex = iterationIndex;
     Operations     = operations;
     Nanoseconds    = nanoseconds;
     LaunchIndex    = launchIndex;
 }
Esempio n. 16
0
 /// <summary>
 /// Creates an instance of <see cref="Measurement"/> struct.
 /// </summary>
 /// <param name="launchIndex"></param>
 /// <param name="iterationMode"></param>
 /// <param name="iterationIndex"></param>
 /// <param name="operations">The number of operations performed.</param>
 /// <param name="nanoseconds">The total number of nanoseconds it took to perform all operations.</param>
 /// <param name="encoding">encoding to display value.</param>
 public Measurement(int launchIndex, IterationMode iterationMode, int iterationIndex, long operations, double nanoseconds, Encoding encoding = null)
 {
     Encoding       = encoding;
     Operations     = operations;
     Nanoseconds    = nanoseconds;
     LaunchIndex    = launchIndex;
     IterationMode  = iterationMode;
     IterationIndex = iterationIndex;
 }
Esempio n. 17
0
        public string ToOutputLine()
        {
            string alignedIterationMode = IterationMode.ToString().PadRight(IterationModeNameMaxWidth, ' ');

            // Usually, a benchmarks takes more than 10 iterations (rarely more than 99)
            // PadLeft(2, ' ') looks like a good trade-off between alignment and amount of characters
            string alignedIterationIndex = IterationIndex.ToString().PadLeft(2, ' ');

            return($"{alignedIterationMode} {alignedIterationIndex}: {GetDisplayValue()}");
        }
Esempio n. 18
0
        private void HandleIterationEvent(int processId, double timeStampRelative, IterationMode iterationMode, long totalOperations)
        {
            // if given process emits Benchmarking events it's the process that we care about
            if (!processIdToData.ContainsKey(processId))
            {
                processIdToData.Add(processId, new ProcessMetrics());
            }

            processIdToData[processId].HandleIterationEvent(timeStampRelative, iterationMode, totalOperations);
        }
 private void AutoTest(Func<IterationData, TimeInterval> measure, int min, int max = -1, IterationMode mode = IterationMode.MainWarmup)
 {
     if (max == -1)
         max = min;
     var job = Job.Default;
     var stage = CreateStage(job, measure);
     var measurements = stage.Run(1, mode, true, 1);
     int count = measurements.Count;
     output.WriteLine($"MeasurementCount = {count} (Min= {min}, Max = {max})");
     Assert.InRange(count, min, max);
 }
        private List<Measurement> RunSpecific(long invokeCount, IterationMode iterationMode, int iterationCount, int unrollFactor)
        {
            var measurements = new List<Measurement>(MaxIterationCount);

            for (int i = 0; i < iterationCount; i++)
                measurements.Add(RunIteration(iterationMode, i + 1, invokeCount, unrollFactor));

            if (!IsDiagnoserAttached) WriteLine();

            return measurements;
        }
        private List <Measurement> RunSpecific(long invokeCount, IterationMode iterationMode, int iterationCount)
        {
            var measurements = new List <Measurement>(iterationCount);

            for (int i = 0; i < iterationCount; i++)
            {
                measurements.Add(RunIteration(iterationMode, i + 1, invokeCount));
            }
            WriteLine();
            return(measurements);
        }
        private List <Measurement> RunSpecific(long invokeCount, IterationMode iterationMode, int iterationCount, int unrollFactor)
        {
            var measurements = new List <Measurement>(MaxIterationCount);

            for (int i = 0; i < iterationCount; i++)
            {
                measurements.Add(RunIteration(iterationMode, IterationStage.Warmup, i + 1, invokeCount, unrollFactor));
            }

            WriteLine();

            return(measurements);
        }
Esempio n. 23
0
    public void UpdateLineRenderer(IterationMode mode, int resolution)
    {
        if (lineRenderer == null)
        {
            return;
        }

        List <Vector3> tempPoints = new List <Vector3>();

        switch (mode)
        {
        case IterationMode.Linear:
        {
            for (int i = 0; i < curve.CountSegments; i++)
            {
                for (float p = 0f; p < 1f; p += 1.0f / resolution)
                {
                    tempPoints.Add(curve.Evaluate(i, p));
                }

                // Manually adding last position due to floating point inaccuracies
                if (i >= curve.CountSegments - 1)
                {
                    tempPoints.Add(curve.Evaluate(i, 1.0f));
                }
            }

            break;
        }

        case IterationMode.Curvature:
        {
            break;
        }

        default:
        {
            break;
        }
        }

        lineRenderer.positionCount = tempPoints.Count;
        lineRenderer.SetPositions(tempPoints.ToArray());
        lineRenderer.startWidth = curve.s_displayWidthCurve;
        lineRenderer.endWidth   = curve.s_displayWidthCurve;
        if (lineRenderer.sharedMaterial == null)
        {
            var tempMat = Resources.Load("Materials/XplinesLineRenderer", typeof(Material)) as Material;
            lineRenderer.sharedMaterial = tempMat;
        }
    }
        private List <Measurement> RunSpecific(long invokeCount, IterationMode iterationMode, int iterationCount, int unrollFactor)
        {
            for (int i = 0; i < iterationCount; i++)
            {
                measurements.Add(RunIteration(iterationMode, i + 1, invokeCount, unrollFactor));
            }

            if (!IsDiagnoserAttached)
            {
                WriteLine();
            }

            return(measurements);
        }
Esempio n. 25
0
        public virtual IStoppingCriteria CreateWarmup(Job job, IResolver resolver, IterationMode mode, RunStrategy runStrategy)
        {
            switch (mode)
            {
            case IterationMode.Overhead:
                return(CreateWarmupOverhead());

            case IterationMode.Workload:
                return(CreateWarmupWorkload(job, resolver, runStrategy));

            default:
                throw new ArgumentOutOfRangeException(nameof(mode), mode, null);
            }
        }
Esempio n. 26
0
        private void RunCore(
            IterationMode iterationMode,
            int repeatCount,
            List <Measurement> measurements)
        {
            DebugCode.BugIf(measurements.Count > 0, "measurements not empty.");
            DebugCode.BugIf(measurements.Capacity < repeatCount, "measurements capacity not set.");

            var action = iterationMode.IsIdle() ? IdleAction : MainAction;
            var resultIterationsCount = ResultIterationsCount;

            // TODO: reenable after https://github.com/dotnet/BenchmarkDotNet/issues/302#issuecomment-262057686
            //if (!iterationMode.IsIdle())
            //	SetupAction?.Invoke();

            ForceGcCollect();
            if (ForceAllocations)             // DONTTOUCH: DO NOT merge loops as it will produce inaccurate results for microbenchmarks.
            {
                for (var i = 0; i < repeatCount; i++)
                {
                    ForceGcCollect();

                    var clock = Clock.Start();
                    action(resultIterationsCount);
                    var clockSpan = clock.Stop();

                    measurements.Add(
                        new Measurement(0, iterationMode, i + 1, 1, clockSpan.GetNanoseconds()));
                }
            }
            else
            {
                for (var i = 0; i < repeatCount; i++)
                {
                    var clock = Clock.Start();
                    action(resultIterationsCount);
                    var clockSpan = clock.Stop();

                    measurements.Add(
                        new Measurement(0, iterationMode, i + 1, 1, clockSpan.GetNanoseconds()));
                }
            }

            ForceGcCollect();
            // TODO: reenable after https://github.com/dotnet/BenchmarkDotNet/issues/302#issuecomment-262057686
            //if (!iterationMode.IsIdle())
            //	CleanupAction?.Invoke();
        }
        private List<Measurement> RunAuto(long invokeCount, IterationMode iterationMode, int unrollFactor)
        {
            var measurements = new List<Measurement>(MaxIterationCount);
            int iterationCounter = 0;
            while (true)
            {
                iterationCounter++;
                measurements.Add(RunIteration(iterationMode, iterationCounter, invokeCount, unrollFactor));
                if (IsWarmupFinished(measurements, iterationMode))
                    break;
            }
            if (!IsDiagnoserAttached)
                WriteLine();

            return measurements;
        }
        private static IList <Measurement> RunTarget(
            Func <MultiInvokeInput, Measurement> multiInvoke, long invokeCount, IterationMode iterationMode, Count iterationCount)
        {
            var measurements = new List <Measurement>();

            if (iterationCount.IsAuto)
            {
                int  iterationCounter   = 0;
                bool isIdle             = ShouldCallIdle(iterationMode);
                var  maxAcceptableError = isIdle ? TargetIdleAutoMaxAcceptableError : TargetMainAutoMaxAcceptableError;

                ForceGcCollect();

                while (true)
                {
                    iterationCounter++;
                    var measurement = multiInvoke(new MultiInvokeInput(iterationMode, iterationCounter, invokeCount));
                    measurements.Add(measurement);
                    var statistics = new Statistics(measurements.Select(m => m.Nanoseconds));
                    var statisticsWithoutOutliers = new Statistics(statistics.WithoutOutliers());
                    if (iterationCounter >= TargetAutoMinIterationCount &&
                        statisticsWithoutOutliers.StandardError < maxAcceptableError * statisticsWithoutOutliers.Mean)
                    {
                        break;
                    }
                    if (isIdle && iterationCounter >= TargetIdleAutoMaxIterationCount)
                    {
                        break;
                    }
                }

                ForceGcCollect();
            }
            else
            {
                ForceGcCollect();

                for (int i = 0; i < iterationCount; i++)
                {
                    measurements.Add(multiInvoke(new MultiInvokeInput(IterationMode.MainTarget, i + 1, invokeCount)));
                }

                ForceGcCollect();
            }
            Console.WriteLine();
            return(measurements);
        }
Esempio n. 29
0
        private void RunCore <T>(
            Action setupAction, Func <T> targetAction, IterationMode iterationMode, Count iterationCount)
        {
            ForceGcCollect();

            setupAction();
            for (int i = 0; i < iterationCount; i++)
            {
                var chronometer = Chronometer.Start();
                targetAction();
                var clockSpan   = chronometer.Stop();
                var measurement = new Measurement(0, iterationMode, i + 1, 1, clockSpan.GetNanoseconds());
                _allMeasurements.Add(measurement);
            }

            ForceGcCollect();
        }
        private List <Measurement> RunAuto(long invokeCount, IterationMode iterationMode)
        {
            int iterationCounter = 0;
            var measurements     = new List <Measurement>(MaxIterationCount);

            while (true)
            {
                iterationCounter++;
                measurements.Add(RunIteration(iterationMode, iterationCounter, invokeCount));
                if (IsWarmupFinished(measurements, iterationMode))
                {
                    break;
                }
            }
            WriteLine();
            return(measurements);
        }
Esempio n. 31
0
        private Measurement MultiInvoke <T>(IterationMode mode, int index, Action setupAction, Func <T> targetAction, long invocationCount, long operationsPerInvoke, T returnHolder = default(T))
        {
            State.Instance.IterationMode = mode;
            State.Instance.Iteration     = index;

            var totalOperations = invocationCount * operationsPerInvoke;

            setupAction();
            ClockSpan clockSpan;

            GcCollect();
            if (invocationCount == 1)
            {
                var chronometer = Chronometer.Start();
                returnHolder = targetAction();
                clockSpan    = chronometer.Stop();
            }
            else if (invocationCount < int.MaxValue)
            {
                int intInvocationCount = (int)invocationCount;
                var chronometer        = Chronometer.Start();
                for (int i = 0; i < intInvocationCount; i++)
                {
                    State.Instance.Operation = i;
                    returnHolder             = targetAction();
                }
                clockSpan = chronometer.Stop();
            }
            else
            {
                var chronometer = Chronometer.Start();
                for (long i = 0; i < invocationCount; i++)
                {
                    State.Instance.Operation = i;
                    returnHolder             = targetAction();
                }
                clockSpan = chronometer.Stop();
            }
            multiInvokeReturnHolder = returnHolder;
            var measurement = new Measurement(0, mode, index, totalOperations, clockSpan.GetNanoseconds());

            Console.WriteLine(measurement.ToOutputLine());
            GcCollect();
            return(measurement);
        }
Esempio n. 32
0
        public IEnumerable <LinkedListNode <T> > GetNodeEnumerable(IterationMode mode           = IterationMode.Linear,
                                                                   IterationDirection direction = IterationDirection.Forward)
        {
            switch (mode)
            {
            case IterationMode.Linear:
                return(LinearEnumerable(direction));

            case IterationMode.Circular:
                return(CircularEnumerable(direction));

            case IterationMode.Harmonic:
                return(HarmonicEnumerable(direction));

            default:
                return(null);
            }
        }
Esempio n. 33
0
    public void Start()
    {
        //initialze object references
        selectionRef = Resources.Load("Selection") as GameObject;
        outputRef    = Resources.Load("Output") as GameObject;

        //switching algorithms
        aMax = (int)Enum.GetValues(typeof(Algorithm)).Cast <Algorithm>().Max();
        aMin = (int)Enum.GetValues(typeof(Algorithm)).Cast <Algorithm>().Min();

        //switching iteration modes
        iMax   = (int)Enum.GetValues(typeof(IterationMode)).Cast <IterationMode>().Max();
        iMin   = (int)Enum.GetValues(typeof(IterationMode)).Cast <IterationMode>().Min();
        player = GetComponent <Player>();

        //defaults
        selectedAlgorithm = 0;
        iterationMode     = 0;
    }
        private List <Measurement> RunAuto(long invokeCount, IterationMode iterationMode, int unrollFactor)
        {
            int iterationCounter = 0;

            while (true)
            {
                iterationCounter++;
                measurements.Add(RunIteration(iterationMode, iterationCounter, invokeCount, unrollFactor));
                if (IsWarmupFinished(measurements, iterationMode))
                {
                    break;
                }
            }
            if (!IsDiagnoserAttached)
            {
                WriteLine();
            }

            return(measurements);
        }
        private static bool IsWarmupFinished(List<Measurement> measurements, IterationMode iterationMode)
        {
            int n = measurements.Count;
            if (n >= MaxIterationCount || (iterationMode.IsIdle() && n >= MaxIdleItertaionCount))
                return true;
            if (n < MinIterationCount)
                return false;

            int dir = -1, changeCount = 0;
            for (int i = 1; i < n; i++)
            {
                int nextDir = Math.Sign(measurements[i].Nanoseconds - measurements[i - 1].Nanoseconds);
                if (nextDir != dir || nextDir == 0)
                {
                    dir = nextDir;
                    changeCount++;
                }
            }

            return changeCount >= 4;
        }
        private static void RunWarmup(
            Func <MultiInvokeInput, Measurement> multiInvoke, long invokeCount, IterationMode iterationMode, Count iterationCount)
        {
            if (iterationCount.IsAuto)
            {
                ForceGcCollect();

                int         iterationCounter    = 0;
                Measurement previousMeasurement = null;
                int         upCount             = 0;
                while (true)
                {
                    iterationCounter++;
                    var measurement = multiInvoke(new MultiInvokeInput(iterationMode, iterationCounter, invokeCount));
                    if (previousMeasurement != null && measurement.Nanoseconds > previousMeasurement.Nanoseconds - 0.1)
                    {
                        upCount++;
                    }
                    if (iterationCounter >= WarmupAutoMinIterationCount && upCount >= 3)
                    {
                        break;
                    }
                    previousMeasurement = measurement;
                }

                ForceGcCollect();
            }
            else
            {
                ForceGcCollect();

                for (int i = 0; i < iterationCount; i++)
                {
                    multiInvoke(new MultiInvokeInput(IterationMode.MainWarmup, i + 1, invokeCount));
                }

                ForceGcCollect();
            }
            Console.WriteLine();
        }
        private List <Measurement> RunAuto(long invokeCount, IterationMode iterationMode, int unrollFactor)
        {
            var measurements = measurementsPool.Next();
            var measurementsForStatistics = measurementsPool.Next();

            int    iterationCounter          = 0;
            bool   isIdle                    = iterationMode.IsIdle();
            double effectiveMaxRelativeError = isIdle ? MaxIdleRelativeError : maxRelativeError;

            while (true)
            {
                iterationCounter++;
                var measurement = RunIteration(iterationMode, iterationCounter, invokeCount, unrollFactor);
                measurements.Add(measurement);
                measurementsForStatistics.Add(measurement);

                var    statistics  = MeasurementsStatistics.Calculate(measurementsForStatistics, removeOutliers);
                double actualError = statistics.ConfidenceInterval.Margin;

                double maxError1 = effectiveMaxRelativeError * statistics.Mean;
                double maxError2 = maxAbsoluteError?.Nanoseconds ?? double.MaxValue;
                double maxError  = Math.Min(maxError1, maxError2);

                if (iterationCounter >= MinIterationCount && actualError < maxError)
                {
                    break;
                }

                if (iterationCounter >= MaxIterationCount || (isIdle && iterationCounter >= MaxIdleIterationCount))
                {
                    break;
                }
            }
            if (!IsDiagnoserAttached)
            {
                WriteLine();
            }
            return(measurements);
        }
 internal List<Measurement> Run(long invokeCount, IterationMode iterationMode, bool runAuto, int unrollFactor)
     => runAuto || warmupCount == null
         ? RunAuto(invokeCount, iterationMode, unrollFactor)
         : RunSpecific(invokeCount, iterationMode, warmupCount.Value, unrollFactor);
 protected Measurement RunIteration(IterationMode mode, int index, long invokeCount, int unrollFactor)
 {
     if (invokeCount % unrollFactor != 0)
         throw new ArgumentOutOfRangeException($"InvokeCount({invokeCount}) should be a multiple of UnrollFactor({unrollFactor}).");
     return engine.RunIteration(new IterationData(mode, index, invokeCount, unrollFactor));
 }
 internal IReadOnlyList<Measurement> Run(long invokeCount, IterationMode iterationMode, bool runAuto, int unrollFactor)
     => runAuto || targetCount == null
         ? RunAuto(invokeCount, iterationMode, unrollFactor)
         : RunSpecific(invokeCount, iterationMode, targetCount.Value, unrollFactor);