コード例 #1
0
        /// <summary>Creates the <see cref="BurstModeEngine"/>.</summary>
        /// <param name="engineParameters">The engine parameters.</param>
        /// <returns>Instance of <see cref="BurstModeEngine"/>.</returns>
        public IEngine Create(EngineParameters engineParameters)
        {
            if (engineParameters.MainAction == null)
            {
                throw new ArgumentNullException(nameof(engineParameters.MainAction));
            }
            if (engineParameters.IdleAction == null)
            {
                throw new ArgumentNullException(nameof(engineParameters.IdleAction));
            }
            if (engineParameters.TargetJob == null)
            {
                throw new ArgumentNullException(nameof(engineParameters.TargetJob));
            }

            var targetJob = engineParameters.TargetJob;

            if (!targetJob.HasValue(RunMode.InvocationCountCharacteristic) ||
                !targetJob.HasValue(RunMode.WarmupCountCharacteristic) ||
                !targetJob.HasValue(RunMode.TargetCountCharacteristic))
            {
                throw new ArgumentException(
                          $"Please set the {RunMode.InvocationCountCharacteristic.FullId}," +
                          $"{RunMode.WarmupCountCharacteristic.FullId} and " +
                          $"{RunMode.TargetCountCharacteristic.FullId} values .",
                          nameof(engineParameters));
            }

            return(new BurstModeEngine(engineParameters));
        }
コード例 #2
0
 private static Engine CreateSingleActionEngine(EngineParameters engineParameters)
 => CreateEngine(engineParameters,
                 engineParameters.TargetJob
                 .WithInvocationCount(1).WithUnrollFactor(1) // run the benchmark exactly once per iteration
                 .WithEvaluateOverhead(false),               // it's something very time consuming, it overhead is too small compared to total time
                                                             // todo: consider if we should set the warmup count to 2
                 engineParameters.OverheadActionNoUnroll,
                 engineParameters.WorkloadActionNoUnroll);
コード例 #3
0
 private static Engine CreateEngine(EngineParameters engineParameters, Job job, Action <long> idle, Action <long> main)
 => new Engine(
     engineParameters.Host,
     EngineParameters.DefaultResolver,
     engineParameters.Dummy1Action,
     engineParameters.Dummy2Action,
     engineParameters.Dummy3Action,
     idle,
     main,
     job,
     engineParameters.GlobalSetupAction,
     engineParameters.GlobalCleanupAction,
     engineParameters.IterationSetupAction,
     engineParameters.IterationCleanupAction,
     engineParameters.OperationsPerInvoke,
     engineParameters.MeasureGcStats);
コード例 #4
0
        public IEngine Create(EngineParameters engineParameters)
        {
            if (engineParameters.MainAction == null)
                throw new ArgumentNullException(nameof(engineParameters.MainAction));
            if (engineParameters.IdleAction == null)
                throw new ArgumentNullException(nameof(engineParameters.IdleAction));
            if(engineParameters.TargetJob == null)
                throw new ArgumentNullException(nameof(engineParameters.TargetJob));

            return new Engine(
                engineParameters.IdleAction,
                engineParameters.MainAction,
                engineParameters.TargetJob,
                engineParameters.SetupAction,
                engineParameters.CleanupAction,
                engineParameters.OperationsPerInvoke,
                engineParameters.IsDiagnoserAttached);
        }
コード例 #5
0
ファイル: EngineFactory.cs プロジェクト: aritryakumar/dotnet
        public IEngine Create(EngineParameters engineParameters)
        {
            if (engineParameters.MainAction == null)
            {
                throw new ArgumentNullException(nameof(engineParameters.MainAction));
            }
            if (engineParameters.Dummy1Action == null)
            {
                throw new ArgumentNullException(nameof(engineParameters.Dummy1Action));
            }
            if (engineParameters.Dummy2Action == null)
            {
                throw new ArgumentNullException(nameof(engineParameters.Dummy2Action));
            }
            if (engineParameters.Dummy3Action == null)
            {
                throw new ArgumentNullException(nameof(engineParameters.Dummy3Action));
            }
            if (engineParameters.IdleAction == null)
            {
                throw new ArgumentNullException(nameof(engineParameters.IdleAction));
            }
            if (engineParameters.TargetJob == null)
            {
                throw new ArgumentNullException(nameof(engineParameters.TargetJob));
            }

            return(new Engine(
                       engineParameters.Host,
                       engineParameters.Dummy1Action,
                       engineParameters.Dummy2Action,
                       engineParameters.Dummy3Action,
                       engineParameters.IdleAction,
                       engineParameters.MainAction,
                       engineParameters.TargetJob,
                       engineParameters.GlobalSetupAction,
                       engineParameters.GlobalCleanupAction,
                       engineParameters.IterationSetupAction,
                       engineParameters.IterationCleanupAction,
                       engineParameters.OperationsPerInvoke,
                       engineParameters.MeasureGcStats));
        }
コード例 #6
0
        public IEngine Create(EngineParameters engineParameters)
        {
            if (engineParameters.MainAction == null)
            {
                throw new ArgumentNullException(nameof(engineParameters.MainAction));
            }
            if (engineParameters.Dummy1Action == null)
            {
                throw new ArgumentNullException(nameof(engineParameters.Dummy1Action));
            }
            if (engineParameters.Dummy2Action == null)
            {
                throw new ArgumentNullException(nameof(engineParameters.Dummy2Action));
            }
            if (engineParameters.Dummy3Action == null)
            {
                throw new ArgumentNullException(nameof(engineParameters.Dummy3Action));
            }
            if (engineParameters.IdleAction == null)
            {
                throw new ArgumentNullException(nameof(engineParameters.IdleAction));
            }
            if (engineParameters.TargetJob == null)
            {
                throw new ArgumentNullException(nameof(engineParameters.TargetJob));
            }

            return(new Engine(
                       engineParameters.Dummy1Action,
                       engineParameters.Dummy2Action,
                       engineParameters.Dummy3Action,
                       engineParameters.IdleAction,
                       engineParameters.MainAction,
                       engineParameters.TargetJob,
                       engineParameters.SetupAction,
                       engineParameters.CleanupAction,
                       engineParameters.OperationsPerInvoke,
                       engineParameters.IsDiagnoserAttached));
        }
コード例 #7
0
        /// <summary>Initializes a new instance of the <see cref="BurstModeEngine"/> class.</summary>
        /// <param name="engineParameters">The engine parameters.</param>
        public BurstModeEngine(EngineParameters engineParameters)
        {
            _engineParameters = engineParameters;

            Resolver = new CompositeResolver(
                EnvResolver.Instance,
                InfrastructureResolver.Instance,
                EngineResolver.Instance);

            var targetJob = engineParameters.TargetJob;

            Clock            = targetJob.ResolveValue(InfrastructureMode.ClockCharacteristic, Resolver);
            ForceAllocations = targetJob.ResolveValue(GcMode.ForceCharacteristic, Resolver);
            UnrollFactor     = targetJob.ResolveValue(RunMode.UnrollFactorCharacteristic, Resolver);
            Strategy         = targetJob.ResolveValue(RunMode.RunStrategyCharacteristic, Resolver);
            EvaluateOverhead = targetJob.ResolveValue(AccuracyMode.EvaluateOverheadCharacteristic, Resolver);
            RemoveOutliers   = targetJob.ResolveValue(AccuracyMode.RemoveOutliersCharacteristic, Resolver);

            InvocationCount = targetJob.ResolveValue(RunMode.InvocationCountCharacteristic, Resolver);
            WarmupCount     = targetJob.ResolveValueAsNullable(RunMode.WarmupCountCharacteristic) ?? 1;
            TargetCount     = targetJob.ResolveValueAsNullable(RunMode.TargetCountCharacteristic) ?? 1;

            IdleWarmupList = new List <Measurement>(WarmupCount);
            WarmupList     = new List <Measurement>(WarmupCount);
            IdleTargetList = new List <Measurement>(TargetCount);
            TargetList     = new List <Measurement>(TargetCount);

            var resultCount = OperationsPerInvoke * InvocationCount;

            if (resultCount % UnrollFactor != 0)
            {
                throw new ArgumentOutOfRangeException(
                          $"InvokeCount({resultCount}) should be a multiple of UnrollFactor({UnrollFactor}).");
            }
            ResultIterationsCount = resultCount / UnrollFactor;
        }
コード例 #8
0
        public IEngine CreateReadyToRun(EngineParameters engineParameters)
        {
            if (engineParameters.WorkloadActionNoUnroll == null)
            {
                throw new ArgumentNullException(nameof(engineParameters.WorkloadActionNoUnroll));
            }
            if (engineParameters.WorkloadActionUnroll == null)
            {
                throw new ArgumentNullException(nameof(engineParameters.WorkloadActionUnroll));
            }
            if (engineParameters.Dummy1Action == null)
            {
                throw new ArgumentNullException(nameof(engineParameters.Dummy1Action));
            }
            if (engineParameters.Dummy2Action == null)
            {
                throw new ArgumentNullException(nameof(engineParameters.Dummy2Action));
            }
            if (engineParameters.Dummy3Action == null)
            {
                throw new ArgumentNullException(nameof(engineParameters.Dummy3Action));
            }
            if (engineParameters.OverheadActionNoUnroll == null)
            {
                throw new ArgumentNullException(nameof(engineParameters.OverheadActionNoUnroll));
            }
            if (engineParameters.OverheadActionUnroll == null)
            {
                throw new ArgumentNullException(nameof(engineParameters.OverheadActionUnroll));
            }
            if (engineParameters.TargetJob == null)
            {
                throw new ArgumentNullException(nameof(engineParameters.TargetJob));
            }

            engineParameters.GlobalSetupAction?.Invoke(); // whatever the settings are, we MUST call global setup here, the global cleanup is part of Engine's Dispose

            if (!engineParameters.NeedsJitting)           // just create the engine, do NOT jit
            {
                return(CreateMultiActionEngine(engineParameters));
            }

            int jitIndex = 0;

            if (engineParameters.HasInvocationCount || engineParameters.HasUnrollFactor) // it's a job with explicit configuration, just create the engine and jit it
            {
                var warmedUpMultiActionEngine = CreateMultiActionEngine(engineParameters);

                DeadCodeEliminationHelper.KeepAliveWithoutBoxing(Jit(warmedUpMultiActionEngine, ++jitIndex, invokeCount: engineParameters.UnrollFactor, unrollFactor: engineParameters.UnrollFactor));

                return(warmedUpMultiActionEngine);
            }

            var singleActionEngine   = CreateSingleActionEngine(engineParameters);
            var singleInvocationTime = Jit(singleActionEngine, ++jitIndex, invokeCount: 1, unrollFactor: 1);

            if (singleInvocationTime > engineParameters.IterationTime)
            {
                return(singleActionEngine); // executing once takes longer than iteration time => long running benchmark, needs no pilot and no overhead
            }
            int defaultUnrollFactor = Job.Default.ResolveValue(RunMode.UnrollFactorCharacteristic, EngineParameters.DefaultResolver);

            double timesPerIteration = engineParameters.IterationTime / singleInvocationTime; // how many times can we run given benchmark per iteration

            if (timesPerIteration < 1.5)                                                      // example: IterationTime is 0.5s, but single invocation takes 0.4s => we don't want to run it twice per iteration
            {
                return(singleActionEngine);
            }

            int roundedUpTimesPerIteration = (int)Math.Ceiling(timesPerIteration);

            if (roundedUpTimesPerIteration < defaultUnrollFactor) // if we run it defaultUnrollFactor times per iteration, it's going to take longer than IterationTime
            {
                var needsPilot = engineParameters.TargetJob
                                 .WithUnrollFactor(1)          // we don't want to use unroll factor!
                                 .WithMinInvokeCount(2)        // the minimum is 2 (not the default 4 which can be too much and not 1 which we already know is not enough)
                                 .WithEvaluateOverhead(false); // it's something very time consuming, it overhead is too small compared to total time

                return(CreateEngine(engineParameters, needsPilot, engineParameters.OverheadActionNoUnroll, engineParameters.WorkloadActionNoUnroll));
            }

            var multiActionEngine = CreateMultiActionEngine(engineParameters);

            DeadCodeEliminationHelper.KeepAliveWithoutBoxing(Jit(multiActionEngine, ++jitIndex, invokeCount: defaultUnrollFactor, unrollFactor: defaultUnrollFactor));

            return(multiActionEngine);
        }
コード例 #9
0
 private static Engine CreateMultiActionEngine(EngineParameters engineParameters)
 => CreateEngine(engineParameters, engineParameters.TargetJob, engineParameters.OverheadActionUnroll, engineParameters.WorkloadActionUnroll);
コード例 #10
0
 public IEngine Create(EngineParameters engineParameters) 
     => new CustomEngine
     {
         CleanupAction = engineParameters.CleanupAction,
         SetupAction = engineParameters.SetupAction
     };
コード例 #11
0
 private static Engine CreateMultiActionEngine(EngineParameters engineParameters)
 => CreateEngine(engineParameters, engineParameters.TargetJob, engineParameters.IdleActionUnroll, engineParameters.MainActionUnroll);
コード例 #12
0
        public IEngine CreateReadyToRun(EngineParameters engineParameters)
        {
            if (engineParameters.WorkloadActionNoUnroll == null)
            {
                throw new ArgumentNullException(nameof(engineParameters.WorkloadActionNoUnroll));
            }
            if (engineParameters.WorkloadActionUnroll == null)
            {
                throw new ArgumentNullException(nameof(engineParameters.WorkloadActionUnroll));
            }
            if (engineParameters.Dummy1Action == null)
            {
                throw new ArgumentNullException(nameof(engineParameters.Dummy1Action));
            }
            if (engineParameters.Dummy2Action == null)
            {
                throw new ArgumentNullException(nameof(engineParameters.Dummy2Action));
            }
            if (engineParameters.Dummy3Action == null)
            {
                throw new ArgumentNullException(nameof(engineParameters.Dummy3Action));
            }
            if (engineParameters.OverheadActionNoUnroll == null)
            {
                throw new ArgumentNullException(nameof(engineParameters.OverheadActionNoUnroll));
            }
            if (engineParameters.OverheadActionUnroll == null)
            {
                throw new ArgumentNullException(nameof(engineParameters.OverheadActionUnroll));
            }
            if (engineParameters.TargetJob == null)
            {
                throw new ArgumentNullException(nameof(engineParameters.TargetJob));
            }

            engineParameters.GlobalSetupAction?.Invoke(); // whatever the settings are, we MUST call global setup here, the global cleanup is part of Engine's Dispose

            if (!engineParameters.NeedsJitting)           // just create the engine, do NOT jit
            {
                return(CreateMultiActionEngine(engineParameters));
            }

            int jitIndex = 0;

            if (engineParameters.HasInvocationCount || engineParameters.HasUnrollFactor) // it's a job with explicit configuration, just create the engine and jit it
            {
                var warmedUpMultiActionEngine = CreateMultiActionEngine(engineParameters);

                DeadCodeEliminationHelper.KeepAliveWithoutBoxing(Jit(warmedUpMultiActionEngine, ++jitIndex, invokeCount: engineParameters.UnrollFactor, unrollFactor: engineParameters.UnrollFactor));

                return(warmedUpMultiActionEngine);
            }

            var    singleActionEngine   = CreateSingleActionEngine(engineParameters);
            var    singleInvocationTime = Jit(singleActionEngine, ++jitIndex, invokeCount: 1, unrollFactor: 1);
            double timesPerIteration    = engineParameters.IterationTime / singleInvocationTime; // how many times can we run given benchmark per iteration

            if ((timesPerIteration < 1.5) && (singleInvocationTime < TimeInterval.FromSeconds(10.0)))
            {
                // if the Jitting took more than IterationTime/1.5 but still less than 10s (a magic number based on observations of reported bugs)
                // we call it one more time to see if Jitting itself has not dominated the first invocation
                // if it did, it should NOT be a single invocation engine (see #837, #1337, #1338, and #1780)
                singleInvocationTime = Jit(singleActionEngine, ++jitIndex, invokeCount: 1, unrollFactor: 1);
                timesPerIteration    = engineParameters.IterationTime / singleInvocationTime;
            }

            // executing once takes longer than iteration time => long running benchmark, needs no pilot and no overhead
            // Or executing twice would put us well past the iteration time ==> needs no pilot and no overhead
            if (timesPerIteration < 1.5)
            {
                return(singleActionEngine);
            }

            int defaultUnrollFactor        = Job.Default.ResolveValue(RunMode.UnrollFactorCharacteristic, EngineParameters.DefaultResolver);
            int roundedUpTimesPerIteration = (int)Math.Ceiling(timesPerIteration);

            if (roundedUpTimesPerIteration < defaultUnrollFactor) // if we run it defaultUnrollFactor times per iteration, it's going to take longer than IterationTime
            {
                var needsPilot = engineParameters.TargetJob
                                 .WithUnrollFactor(1)          // we don't want to use unroll factor!
                                 .WithMinInvokeCount(2)        // the minimum is 2 (not the default 4 which can be too much and not 1 which we already know is not enough)
                                 .WithEvaluateOverhead(false); // it's something very time consuming, it overhead is too small compared to total time

                return(CreateEngine(engineParameters, needsPilot, engineParameters.OverheadActionNoUnroll, engineParameters.WorkloadActionNoUnroll));
            }

            var multiActionEngine = CreateMultiActionEngine(engineParameters);

            DeadCodeEliminationHelper.KeepAliveWithoutBoxing(Jit(multiActionEngine, ++jitIndex, invokeCount: defaultUnrollFactor, unrollFactor: defaultUnrollFactor));

            return(multiActionEngine);
        }