pass config from runner => executor => diagnoser #412
This commit is contained in:
Родитель
43643ceda4
Коммит
303fff198c
|
@ -22,14 +22,14 @@ namespace BenchmarkDotNet.Diagnosers
|
||||||
public IColumnProvider GetColumnProvider()
|
public IColumnProvider GetColumnProvider()
|
||||||
=> new CompositeColumnProvider(diagnosers.Select(d => d.GetColumnProvider()).ToArray());
|
=> new CompositeColumnProvider(diagnosers.Select(d => d.GetColumnProvider()).ToArray());
|
||||||
|
|
||||||
public void BeforeAnythingElse(Process process, Benchmark benchmark)
|
public void BeforeAnythingElse(DiagnoserActionParameters parameters)
|
||||||
=> diagnosers.ForEach(diagnoser => diagnoser.BeforeAnythingElse(process, benchmark));
|
=> diagnosers.ForEach(diagnoser => diagnoser.BeforeAnythingElse(parameters));
|
||||||
|
|
||||||
public void AfterSetup(Process process, Benchmark benchmark)
|
public void AfterSetup(DiagnoserActionParameters parameters)
|
||||||
=> diagnosers.ForEach(diagnoser => diagnoser.AfterSetup(process, benchmark));
|
=> diagnosers.ForEach(diagnoser => diagnoser.AfterSetup(parameters));
|
||||||
|
|
||||||
public void BeforeMainRun(Process process, Benchmark benchmark)
|
public void BeforeMainRun(DiagnoserActionParameters parameters)
|
||||||
=> diagnosers.ForEach(diagnoser => diagnoser.BeforeMainRun(process, benchmark));
|
=> diagnosers.ForEach(diagnoser => diagnoser.BeforeMainRun(parameters));
|
||||||
|
|
||||||
public void BeforeCleanup() => diagnosers.ForEach(diagnoser => diagnoser.BeforeCleanup());
|
public void BeforeCleanup() => diagnosers.ForEach(diagnoser => diagnoser.BeforeCleanup());
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
using System.Diagnostics;
|
||||||
|
using BenchmarkDotNet.Configs;
|
||||||
|
using BenchmarkDotNet.Running;
|
||||||
|
|
||||||
|
namespace BenchmarkDotNet.Diagnosers
|
||||||
|
{
|
||||||
|
public class DiagnoserActionParameters
|
||||||
|
{
|
||||||
|
public DiagnoserActionParameters(Process process, Benchmark benchmark, IConfig config)
|
||||||
|
{
|
||||||
|
Process = process;
|
||||||
|
Benchmark = benchmark;
|
||||||
|
Config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Process Process { get; }
|
||||||
|
|
||||||
|
public Benchmark Benchmark { get; }
|
||||||
|
|
||||||
|
public IConfig Config { get; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,4 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
|
||||||
using BenchmarkDotNet.Columns;
|
using BenchmarkDotNet.Columns;
|
||||||
using BenchmarkDotNet.Loggers;
|
using BenchmarkDotNet.Loggers;
|
||||||
using BenchmarkDotNet.Running;
|
using BenchmarkDotNet.Running;
|
||||||
|
@ -15,17 +14,17 @@ namespace BenchmarkDotNet.Diagnosers
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// before jitting, warmup
|
/// before jitting, warmup
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void BeforeAnythingElse(Process process, Benchmark benchmark);
|
void BeforeAnythingElse(DiagnoserActionParameters parameters);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// after setup, before run
|
/// after setup, before run
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void AfterSetup(Process process, Benchmark benchmark);
|
void AfterSetup(DiagnoserActionParameters parameters);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// after setup, warmup and pilot but before the main run
|
/// after setup, warmup and pilot but before the main run
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void BeforeMainRun(Process process, Benchmark benchmark);
|
void BeforeMainRun(DiagnoserActionParameters parameters);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// after run, before cleanup
|
/// after run, before cleanup
|
||||||
|
|
|
@ -30,9 +30,9 @@ namespace BenchmarkDotNet.Diagnosers
|
||||||
|
|
||||||
// the following methods are left empty on purpose
|
// the following methods are left empty on purpose
|
||||||
// the action takes places in other process, and the values are gathered by Engine
|
// the action takes places in other process, and the values are gathered by Engine
|
||||||
public void BeforeAnythingElse(Process process, Benchmark benchmark) { }
|
public void BeforeAnythingElse(DiagnoserActionParameters _) { }
|
||||||
public void AfterSetup(Process process, Benchmark benchmark) { }
|
public void AfterSetup(DiagnoserActionParameters _) { }
|
||||||
public void BeforeMainRun(Process process, Benchmark benchmark) { }
|
public void BeforeMainRun(DiagnoserActionParameters _) { }
|
||||||
public void BeforeCleanup() { }
|
public void BeforeCleanup() { }
|
||||||
|
|
||||||
public void DisplayResults(ILogger logger)
|
public void DisplayResults(ILogger logger)
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
namespace BenchmarkDotNet.Loggers
|
||||||
|
{
|
||||||
|
public class NullLogger : ILogger
|
||||||
|
{
|
||||||
|
public static readonly ILogger Instance = new NullLogger();
|
||||||
|
|
||||||
|
private NullLogger() { }
|
||||||
|
|
||||||
|
public void Write(LogKind logKind, string text) { }
|
||||||
|
|
||||||
|
public void WriteLine() { }
|
||||||
|
|
||||||
|
public void WriteLine(LogKind logKind, string text) { }
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using BenchmarkDotNet.Configs;
|
||||||
using BenchmarkDotNet.Diagnosers;
|
using BenchmarkDotNet.Diagnosers;
|
||||||
using BenchmarkDotNet.Engines;
|
using BenchmarkDotNet.Engines;
|
||||||
using BenchmarkDotNet.Running;
|
using BenchmarkDotNet.Running;
|
||||||
|
@ -13,8 +14,9 @@ namespace BenchmarkDotNet.Loggers
|
||||||
private readonly Process process;
|
private readonly Process process;
|
||||||
private readonly Benchmark benchmark;
|
private readonly Benchmark benchmark;
|
||||||
private readonly IDiagnoser diagnoser;
|
private readonly IDiagnoser diagnoser;
|
||||||
|
private readonly DiagnoserActionParameters diagnoserActionParameters;
|
||||||
|
|
||||||
public SynchronousProcessOutputLoggerWithDiagnoser(ILogger logger, Process process, IDiagnoser diagnoser, Benchmark benchmark)
|
public SynchronousProcessOutputLoggerWithDiagnoser(ILogger logger, Process process, IDiagnoser diagnoser, Benchmark benchmark, IConfig config)
|
||||||
{
|
{
|
||||||
if (!process.StartInfo.RedirectStandardOutput)
|
if (!process.StartInfo.RedirectStandardOutput)
|
||||||
{
|
{
|
||||||
|
@ -25,6 +27,10 @@ namespace BenchmarkDotNet.Loggers
|
||||||
this.process = process;
|
this.process = process;
|
||||||
this.diagnoser = diagnoser;
|
this.diagnoser = diagnoser;
|
||||||
this.benchmark = benchmark;
|
this.benchmark = benchmark;
|
||||||
|
diagnoserActionParameters = new DiagnoserActionParameters(
|
||||||
|
process,
|
||||||
|
benchmark,
|
||||||
|
config);
|
||||||
|
|
||||||
LinesWithResults = new List<string>();
|
LinesWithResults = new List<string>();
|
||||||
LinesWithExtraOutput = new List<string>();
|
LinesWithExtraOutput = new List<string>();
|
||||||
|
@ -50,15 +56,15 @@ namespace BenchmarkDotNet.Loggers
|
||||||
}
|
}
|
||||||
else if (line == Engine.Signals.BeforeAnythingElse)
|
else if (line == Engine.Signals.BeforeAnythingElse)
|
||||||
{
|
{
|
||||||
diagnoser?.BeforeAnythingElse(process, benchmark);
|
diagnoser?.BeforeAnythingElse(diagnoserActionParameters);
|
||||||
}
|
}
|
||||||
else if (line == Engine.Signals.AfterSetup)
|
else if (line == Engine.Signals.AfterSetup)
|
||||||
{
|
{
|
||||||
diagnoser?.AfterSetup(process, benchmark);
|
diagnoser?.AfterSetup(diagnoserActionParameters);
|
||||||
}
|
}
|
||||||
else if (line == Engine.Signals.BeforeMainRun)
|
else if (line == Engine.Signals.BeforeMainRun)
|
||||||
{
|
{
|
||||||
diagnoser?.BeforeMainRun(process, benchmark);
|
diagnoser?.BeforeMainRun(diagnoserActionParameters);
|
||||||
}
|
}
|
||||||
else if (line == Engine.Signals.BeforeCleanup)
|
else if (line == Engine.Signals.BeforeCleanup)
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,6 +15,7 @@ using BenchmarkDotNet.Loggers;
|
||||||
using BenchmarkDotNet.Mathematics;
|
using BenchmarkDotNet.Mathematics;
|
||||||
using BenchmarkDotNet.Reports;
|
using BenchmarkDotNet.Reports;
|
||||||
using BenchmarkDotNet.Toolchains;
|
using BenchmarkDotNet.Toolchains;
|
||||||
|
using BenchmarkDotNet.Toolchains.Parameters;
|
||||||
using BenchmarkDotNet.Toolchains.Results;
|
using BenchmarkDotNet.Toolchains.Results;
|
||||||
using BenchmarkDotNet.Validators;
|
using BenchmarkDotNet.Validators;
|
||||||
|
|
||||||
|
@ -247,7 +248,8 @@ namespace BenchmarkDotNet.Running
|
||||||
: " / " + launchCount;
|
: " / " + launchCount;
|
||||||
logger.WriteLineInfo($"// Launch: {launchIndex + 1}{printedLaunchCount}");
|
logger.WriteLineInfo($"// Launch: {launchIndex + 1}{printedLaunchCount}");
|
||||||
|
|
||||||
var executeResult = toolchain.Executor.Execute(buildResult, benchmark, logger, resolver);
|
var executeResult = toolchain.Executor.Execute(
|
||||||
|
new ExecuteParameters(buildResult, benchmark, logger, resolver, config));
|
||||||
|
|
||||||
if (!executeResult.FoundExecutable)
|
if (!executeResult.FoundExecutable)
|
||||||
logger.WriteLineError($"Executable {buildResult.ArtifactsPaths.ExecutablePath} not found");
|
logger.WriteLineError($"Executable {buildResult.ArtifactsPaths.ExecutablePath} not found");
|
||||||
|
@ -285,7 +287,8 @@ namespace BenchmarkDotNet.Running
|
||||||
logger.WriteLineInfo("// Run, Diagnostic");
|
logger.WriteLineInfo("// Run, Diagnostic");
|
||||||
var compositeDiagnoser = config.GetCompositeDiagnoser();
|
var compositeDiagnoser = config.GetCompositeDiagnoser();
|
||||||
|
|
||||||
var executeResult = toolchain.Executor.Execute(buildResult, benchmark, logger, resolver, compositeDiagnoser);
|
var executeResult = toolchain.Executor.Execute(
|
||||||
|
new ExecuteParameters(buildResult, benchmark, logger, resolver, config, compositeDiagnoser));
|
||||||
|
|
||||||
var allRuns = executeResult.Data.Select(line => Measurement.Parse(logger, line, 0)).Where(r => r.IterationMode != IterationMode.Unknown).ToList();
|
var allRuns = executeResult.Data.Select(line => Measurement.Parse(logger, line, 0)).Where(r => r.IterationMode != IterationMode.Unknown).ToList();
|
||||||
gcStats = GcStats.Parse(executeResult.Data.Last());
|
gcStats = GcStats.Parse(executeResult.Data.Last());
|
||||||
|
|
|
@ -3,12 +3,14 @@ using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using BenchmarkDotNet.Characteristics;
|
using BenchmarkDotNet.Characteristics;
|
||||||
|
using BenchmarkDotNet.Configs;
|
||||||
using BenchmarkDotNet.Diagnosers;
|
using BenchmarkDotNet.Diagnosers;
|
||||||
using BenchmarkDotNet.Engines;
|
using BenchmarkDotNet.Engines;
|
||||||
using BenchmarkDotNet.Extensions;
|
using BenchmarkDotNet.Extensions;
|
||||||
using BenchmarkDotNet.Jobs;
|
using BenchmarkDotNet.Jobs;
|
||||||
using BenchmarkDotNet.Loggers;
|
using BenchmarkDotNet.Loggers;
|
||||||
using BenchmarkDotNet.Running;
|
using BenchmarkDotNet.Running;
|
||||||
|
using BenchmarkDotNet.Toolchains.Parameters;
|
||||||
using BenchmarkDotNet.Toolchains.Results;
|
using BenchmarkDotNet.Toolchains.Results;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
|
|
||||||
|
@ -17,23 +19,29 @@ namespace BenchmarkDotNet.Toolchains.DotNetCli
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public class DotNetCliExecutor : IExecutor
|
public class DotNetCliExecutor : IExecutor
|
||||||
{
|
{
|
||||||
public ExecuteResult Execute(BuildResult buildResult, Benchmark benchmark, ILogger logger, IResolver resolver, IDiagnoser diagnoser = null)
|
public ExecuteResult Execute(ExecuteParameters executeParameters)
|
||||||
{
|
{
|
||||||
var executableName = $"{buildResult.ArtifactsPaths.ProgramName}.dll";
|
var executableName = $"{executeParameters.BuildResult.ArtifactsPaths.ProgramName}.dll";
|
||||||
if (!File.Exists(Path.Combine(buildResult.ArtifactsPaths.BinariesDirectoryPath, executableName)))
|
if (!File.Exists(Path.Combine(executeParameters.BuildResult.ArtifactsPaths.BinariesDirectoryPath, executableName)))
|
||||||
{
|
{
|
||||||
logger.WriteLineError($"Did not find {executableName} in {buildResult.ArtifactsPaths.BinariesDirectoryPath}, but the folder contained:");
|
executeParameters.Logger.WriteLineError($"Did not find {executableName} in {executeParameters.BuildResult.ArtifactsPaths.BinariesDirectoryPath}, but the folder contained:");
|
||||||
foreach (var file in new DirectoryInfo(buildResult.ArtifactsPaths.BinariesDirectoryPath).GetFiles("*.*"))
|
foreach (var file in new DirectoryInfo(executeParameters.BuildResult.ArtifactsPaths.BinariesDirectoryPath).GetFiles("*.*"))
|
||||||
logger.WriteLineError(file.Name);
|
executeParameters.Logger.WriteLineError(file.Name);
|
||||||
|
|
||||||
return new ExecuteResult(false, -1, Array.Empty<string>(), Array.Empty<string>());
|
return new ExecuteResult(false, -1, Array.Empty<string>(), Array.Empty<string>());
|
||||||
}
|
}
|
||||||
|
|
||||||
ConsoleHandler.EnsureInitialized(logger);
|
ConsoleHandler.EnsureInitialized(executeParameters.Logger);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return Execute(benchmark, logger, buildResult.ArtifactsPaths, diagnoser, executableName);
|
return Execute(
|
||||||
|
executeParameters.Benchmark,
|
||||||
|
executeParameters.Logger,
|
||||||
|
executeParameters.BuildResult.ArtifactsPaths,
|
||||||
|
executeParameters.Diagnoser,
|
||||||
|
executableName,
|
||||||
|
executeParameters.Config);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
@ -41,7 +49,7 @@ namespace BenchmarkDotNet.Toolchains.DotNetCli
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ExecuteResult Execute(Benchmark benchmark, ILogger logger, ArtifactsPaths artifactsPaths, IDiagnoser diagnoser, string executableName)
|
private ExecuteResult Execute(Benchmark benchmark, ILogger logger, ArtifactsPaths artifactsPaths, IDiagnoser diagnoser, string executableName, IConfig config)
|
||||||
{
|
{
|
||||||
using (var process = new Process
|
using (var process = new Process
|
||||||
{
|
{
|
||||||
|
@ -50,7 +58,7 @@ namespace BenchmarkDotNet.Toolchains.DotNetCli
|
||||||
BuildArgs(diagnoser, executableName))
|
BuildArgs(diagnoser, executableName))
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
var loggerWithDiagnoser = new SynchronousProcessOutputLoggerWithDiagnoser(logger, process, diagnoser, benchmark);
|
var loggerWithDiagnoser = new SynchronousProcessOutputLoggerWithDiagnoser(logger, process, diagnoser, benchmark, config);
|
||||||
|
|
||||||
ConsoleHandler.Instance.SetProcess(process);
|
ConsoleHandler.Instance.SetProcess(process);
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using BenchmarkDotNet.Characteristics;
|
using BenchmarkDotNet.Characteristics;
|
||||||
|
using BenchmarkDotNet.Configs;
|
||||||
using BenchmarkDotNet.Diagnosers;
|
using BenchmarkDotNet.Diagnosers;
|
||||||
using BenchmarkDotNet.Engines;
|
using BenchmarkDotNet.Engines;
|
||||||
using BenchmarkDotNet.Environments;
|
using BenchmarkDotNet.Environments;
|
||||||
|
@ -12,6 +13,7 @@ using BenchmarkDotNet.Loggers;
|
||||||
using BenchmarkDotNet.Jobs;
|
using BenchmarkDotNet.Jobs;
|
||||||
using BenchmarkDotNet.Portability;
|
using BenchmarkDotNet.Portability;
|
||||||
using BenchmarkDotNet.Running;
|
using BenchmarkDotNet.Running;
|
||||||
|
using BenchmarkDotNet.Toolchains.Parameters;
|
||||||
using BenchmarkDotNet.Toolchains.Results;
|
using BenchmarkDotNet.Toolchains.Results;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
|
|
||||||
|
@ -20,21 +22,20 @@ namespace BenchmarkDotNet.Toolchains
|
||||||
[PublicAPI("Used by some of our Superusers that implement their own Toolchains (e.g. Kestrel team)")]
|
[PublicAPI("Used by some of our Superusers that implement their own Toolchains (e.g. Kestrel team)")]
|
||||||
public class Executor : IExecutor
|
public class Executor : IExecutor
|
||||||
{
|
{
|
||||||
public ExecuteResult Execute(BuildResult buildResult, Benchmark benchmark, ILogger logger, IResolver resolver, IDiagnoser compositeDiagnoser = null)
|
public ExecuteResult Execute(ExecuteParameters executeParameters)
|
||||||
{
|
{
|
||||||
var exePath = buildResult.ArtifactsPaths.ExecutablePath;
|
var exePath = executeParameters.BuildResult.ArtifactsPaths.ExecutablePath;
|
||||||
var args = compositeDiagnoser == null ? string.Empty : Engine.Signals.DiagnoserIsAttachedParam;
|
var args = executeParameters.Diagnoser == null ? string.Empty : Engine.Signals.DiagnoserIsAttachedParam;
|
||||||
|
|
||||||
if (!File.Exists(exePath))
|
if (!File.Exists(exePath))
|
||||||
{
|
{
|
||||||
return new ExecuteResult(false, -1, Array.Empty<string>(), Array.Empty<string>());
|
return new ExecuteResult(false, -1, Array.Empty<string>(), Array.Empty<string>());
|
||||||
}
|
}
|
||||||
|
|
||||||
return Execute(benchmark, logger, exePath, null, args, compositeDiagnoser, resolver);
|
return Execute(executeParameters.Benchmark, executeParameters.Logger, exePath, null, args, executeParameters.Diagnoser, executeParameters.Resolver, executeParameters.Config);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ExecuteResult Execute(Benchmark benchmark, ILogger logger, string exePath, string workingDirectory, string args, IDiagnoser diagnoser,
|
private ExecuteResult Execute(Benchmark benchmark, ILogger logger, string exePath, string workingDirectory, string args, IDiagnoser diagnoser, IResolver resolver, IConfig config)
|
||||||
IResolver resolver)
|
|
||||||
{
|
{
|
||||||
ConsoleHandler.EnsureInitialized(logger);
|
ConsoleHandler.EnsureInitialized(logger);
|
||||||
|
|
||||||
|
@ -42,7 +43,7 @@ namespace BenchmarkDotNet.Toolchains
|
||||||
{
|
{
|
||||||
using (var process = new Process { StartInfo = CreateStartInfo(benchmark, exePath, args, workingDirectory, resolver) })
|
using (var process = new Process { StartInfo = CreateStartInfo(benchmark, exePath, args, workingDirectory, resolver) })
|
||||||
{
|
{
|
||||||
var loggerWithDiagnoser = new SynchronousProcessOutputLoggerWithDiagnoser(logger, process, diagnoser, benchmark);
|
var loggerWithDiagnoser = new SynchronousProcessOutputLoggerWithDiagnoser(logger, process, diagnoser, benchmark, config);
|
||||||
|
|
||||||
return Execute(process, benchmark, loggerWithDiagnoser, logger);
|
return Execute(process, benchmark, loggerWithDiagnoser, logger);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,10 @@
|
||||||
using BenchmarkDotNet.Characteristics;
|
using BenchmarkDotNet.Toolchains.Parameters;
|
||||||
using BenchmarkDotNet.Diagnosers;
|
|
||||||
using BenchmarkDotNet.Loggers;
|
|
||||||
using BenchmarkDotNet.Running;
|
|
||||||
using BenchmarkDotNet.Toolchains.Results;
|
using BenchmarkDotNet.Toolchains.Results;
|
||||||
|
|
||||||
namespace BenchmarkDotNet.Toolchains
|
namespace BenchmarkDotNet.Toolchains
|
||||||
{
|
{
|
||||||
public interface IExecutor
|
public interface IExecutor
|
||||||
{
|
{
|
||||||
ExecuteResult Execute(BuildResult buildResult, Benchmark benchmark, ILogger logger, IResolver resolver, IDiagnoser diagnoser = null);
|
ExecuteResult Execute(ExecuteParameters executeParameters);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -13,6 +13,7 @@ using BenchmarkDotNet.Extensions;
|
||||||
using BenchmarkDotNet.Jobs;
|
using BenchmarkDotNet.Jobs;
|
||||||
using BenchmarkDotNet.Loggers;
|
using BenchmarkDotNet.Loggers;
|
||||||
using BenchmarkDotNet.Running;
|
using BenchmarkDotNet.Running;
|
||||||
|
using BenchmarkDotNet.Toolchains.Parameters;
|
||||||
using BenchmarkDotNet.Toolchains.Results;
|
using BenchmarkDotNet.Toolchains.Results;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
|
|
||||||
|
@ -57,24 +58,17 @@ namespace BenchmarkDotNet.Toolchains.InProcess
|
||||||
public bool LogOutput { get; }
|
public bool LogOutput { get; }
|
||||||
|
|
||||||
/// <summary>Executes the specified benchmark.</summary>
|
/// <summary>Executes the specified benchmark.</summary>
|
||||||
/// <param name="buildResult">The build result.</param>
|
public ExecuteResult Execute(ExecuteParameters executeParameters)
|
||||||
/// <param name="benchmark">The benchmark.</param>
|
|
||||||
/// <param name="logger">The logger.</param>
|
|
||||||
/// <param name="resolver">The resolver.</param>
|
|
||||||
/// <param name="diagnoser">The diagnoser.</param>
|
|
||||||
/// <returns>Execution result.</returns>
|
|
||||||
public ExecuteResult Execute(
|
|
||||||
BuildResult buildResult, Benchmark benchmark, ILogger logger, IResolver resolver, IDiagnoser diagnoser = null)
|
|
||||||
{
|
{
|
||||||
// TODO: preallocate buffer for output (no direct logging)?
|
// TODO: preallocate buffer for output (no direct logging)?
|
||||||
var hostLogger = LogOutput ? logger : new CompositeLogger();
|
var hostLogger = LogOutput ? executeParameters.Logger : NullLogger.Instance;
|
||||||
var host = new InProcessHost(benchmark, hostLogger, diagnoser);
|
var host = new InProcessHost(executeParameters.Benchmark, hostLogger, executeParameters.Diagnoser, executeParameters.Config);
|
||||||
|
|
||||||
int exitCode = -1;
|
int exitCode = -1;
|
||||||
var runThread = new Thread(() => exitCode = ExecuteCore(host, benchmark, logger));
|
var runThread = new Thread(() => exitCode = ExecuteCore(host, executeParameters.Benchmark, executeParameters.Logger));
|
||||||
|
|
||||||
#if CLASSIC
|
#if CLASSIC
|
||||||
if (benchmark.Target.Method.GetCustomAttributes<STAThreadAttribute>(false).Any())
|
if (executeParameters.Benchmark.Target.Method.GetCustomAttributes<STAThreadAttribute>(false).Any())
|
||||||
{
|
{
|
||||||
runThread.SetApartmentState(ApartmentState.STA);
|
runThread.SetApartmentState(ApartmentState.STA);
|
||||||
}
|
}
|
||||||
|
@ -87,10 +81,10 @@ namespace BenchmarkDotNet.Toolchains.InProcess
|
||||||
|
|
||||||
if (!runThread.Join((int)timeout.TotalMilliseconds))
|
if (!runThread.Join((int)timeout.TotalMilliseconds))
|
||||||
throw new InvalidOperationException(
|
throw new InvalidOperationException(
|
||||||
$"Benchmark {benchmark.DisplayInfo} takes to long to run. " +
|
$"Benchmark {executeParameters.Benchmark.DisplayInfo} takes to long to run. " +
|
||||||
"Prefer to use out-of-process toolchains for long-running benchmarks.");
|
"Prefer to use out-of-process toolchains for long-running benchmarks.");
|
||||||
|
|
||||||
return GetExecutionResult(host.RunResults, exitCode, logger);
|
return GetExecutionResult(host.RunResults, exitCode, executeParameters.Logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int ExecuteCore(IHost host, Benchmark benchmark, ILogger logger)
|
private int ExecuteCore(IHost host, Benchmark benchmark, ILogger logger)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using BenchmarkDotNet.Configs;
|
||||||
using BenchmarkDotNet.Diagnosers;
|
using BenchmarkDotNet.Diagnosers;
|
||||||
using BenchmarkDotNet.Engines;
|
using BenchmarkDotNet.Engines;
|
||||||
using BenchmarkDotNet.Loggers;
|
using BenchmarkDotNet.Loggers;
|
||||||
|
@ -13,9 +14,6 @@ namespace BenchmarkDotNet.Toolchains.InProcess
|
||||||
/// <seealso cref="IHost"/>
|
/// <seealso cref="IHost"/>
|
||||||
public sealed class InProcessHost : IHost
|
public sealed class InProcessHost : IHost
|
||||||
{
|
{
|
||||||
[NotNull]
|
|
||||||
private readonly Benchmark benchmark;
|
|
||||||
|
|
||||||
[NotNull]
|
[NotNull]
|
||||||
private readonly ILogger logger;
|
private readonly ILogger logger;
|
||||||
|
|
||||||
|
@ -23,13 +21,13 @@ namespace BenchmarkDotNet.Toolchains.InProcess
|
||||||
private readonly IDiagnoser diagnoser;
|
private readonly IDiagnoser diagnoser;
|
||||||
|
|
||||||
[CanBeNull]
|
[CanBeNull]
|
||||||
private readonly Process currentProcess;
|
private readonly DiagnoserActionParameters diagnoserActionParameters;
|
||||||
|
|
||||||
/// <summary>Creates a new instance of <see cref="InProcessHost"/>.</summary>
|
/// <summary>Creates a new instance of <see cref="InProcessHost"/>.</summary>
|
||||||
/// <param name="benchmark">Current benchmark.</param>
|
/// <param name="benchmark">Current benchmark.</param>
|
||||||
/// <param name="logger">Logger for informational output.</param>
|
/// <param name="logger">Logger for informational output.</param>
|
||||||
/// <param name="diagnoser">Diagnosers, if attached.</param>
|
/// <param name="diagnoser">Diagnosers, if attached.</param>
|
||||||
public InProcessHost(Benchmark benchmark, ILogger logger, IDiagnoser diagnoser)
|
public InProcessHost(Benchmark benchmark, ILogger logger, IDiagnoser diagnoser, IConfig config)
|
||||||
{
|
{
|
||||||
if (benchmark == null)
|
if (benchmark == null)
|
||||||
throw new ArgumentNullException(nameof(benchmark));
|
throw new ArgumentNullException(nameof(benchmark));
|
||||||
|
@ -37,13 +35,15 @@ namespace BenchmarkDotNet.Toolchains.InProcess
|
||||||
if (logger == null)
|
if (logger == null)
|
||||||
throw new ArgumentNullException(nameof(logger));
|
throw new ArgumentNullException(nameof(logger));
|
||||||
|
|
||||||
this.benchmark = benchmark;
|
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
this.diagnoser = diagnoser;
|
this.diagnoser = diagnoser;
|
||||||
IsDiagnoserAttached = diagnoser != null;
|
IsDiagnoserAttached = diagnoser != null;
|
||||||
|
|
||||||
if (diagnoser != null)
|
if (diagnoser != null)
|
||||||
currentProcess = Process.GetCurrentProcess();
|
diagnoserActionParameters = new DiagnoserActionParameters(
|
||||||
|
Process.GetCurrentProcess(),
|
||||||
|
benchmark,
|
||||||
|
config);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary><c>True</c> if there are diagnosers attached.</summary>
|
/// <summary><c>True</c> if there are diagnosers attached.</summary>
|
||||||
|
@ -72,15 +72,15 @@ namespace BenchmarkDotNet.Toolchains.InProcess
|
||||||
switch (hostSignal)
|
switch (hostSignal)
|
||||||
{
|
{
|
||||||
case HostSignal.BeforeAnythingElse:
|
case HostSignal.BeforeAnythingElse:
|
||||||
diagnoser?.BeforeAnythingElse(currentProcess, benchmark);
|
diagnoser?.BeforeAnythingElse(diagnoserActionParameters);
|
||||||
WriteLine(Engine.Signals.BeforeAnythingElse);
|
WriteLine(Engine.Signals.BeforeAnythingElse);
|
||||||
break;
|
break;
|
||||||
case HostSignal.AfterSetup:
|
case HostSignal.AfterSetup:
|
||||||
diagnoser?.AfterSetup(currentProcess, benchmark);
|
diagnoser?.AfterSetup(diagnoserActionParameters);
|
||||||
WriteLine(Engine.Signals.AfterSetup);
|
WriteLine(Engine.Signals.AfterSetup);
|
||||||
break;
|
break;
|
||||||
case HostSignal.BeforeMainRun:
|
case HostSignal.BeforeMainRun:
|
||||||
diagnoser?.BeforeMainRun(currentProcess, benchmark);
|
diagnoser?.BeforeMainRun(diagnoserActionParameters);
|
||||||
WriteLine(Engine.Signals.BeforeMainRun);
|
WriteLine(Engine.Signals.BeforeMainRun);
|
||||||
break;
|
break;
|
||||||
case HostSignal.BeforeCleanup:
|
case HostSignal.BeforeCleanup:
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
using BenchmarkDotNet.Characteristics;
|
||||||
|
using BenchmarkDotNet.Configs;
|
||||||
|
using BenchmarkDotNet.Diagnosers;
|
||||||
|
using BenchmarkDotNet.Loggers;
|
||||||
|
using BenchmarkDotNet.Running;
|
||||||
|
using BenchmarkDotNet.Toolchains.Results;
|
||||||
|
|
||||||
|
namespace BenchmarkDotNet.Toolchains.Parameters
|
||||||
|
{
|
||||||
|
public class ExecuteParameters
|
||||||
|
{
|
||||||
|
public ExecuteParameters(BuildResult buildResult, Benchmark benchmark, ILogger logger, IResolver resolver, IConfig config, IDiagnoser diagnoser = null)
|
||||||
|
{
|
||||||
|
BuildResult = buildResult;
|
||||||
|
Benchmark = benchmark;
|
||||||
|
Logger = logger;
|
||||||
|
Resolver = resolver;
|
||||||
|
Config = config;
|
||||||
|
Diagnoser = diagnoser;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BuildResult BuildResult { get; }
|
||||||
|
|
||||||
|
public Benchmark Benchmark { get; }
|
||||||
|
|
||||||
|
public ILogger Logger { get; }
|
||||||
|
|
||||||
|
public IResolver Resolver { get; }
|
||||||
|
|
||||||
|
public IConfig Config { get; }
|
||||||
|
|
||||||
|
public IDiagnoser Diagnoser { get; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,6 +6,7 @@ using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using BenchmarkDotNet.Diagnosers;
|
||||||
using Microsoft.Diagnostics.Tracing;
|
using Microsoft.Diagnostics.Tracing;
|
||||||
using Microsoft.Diagnostics.Tracing.Parsers;
|
using Microsoft.Diagnostics.Tracing.Parsers;
|
||||||
using Microsoft.Diagnostics.Tracing.Session;
|
using Microsoft.Diagnostics.Tracing.Session;
|
||||||
|
@ -24,18 +25,18 @@ namespace BenchmarkDotNet.Diagnostics.Windows
|
||||||
|
|
||||||
protected abstract string SessionNamePrefix { get; }
|
protected abstract string SessionNamePrefix { get; }
|
||||||
|
|
||||||
protected void Start(Process process, Benchmark benchmark)
|
protected void Start(DiagnoserActionParameters parameters)
|
||||||
{
|
{
|
||||||
Cleanup();
|
Cleanup();
|
||||||
|
|
||||||
BenchmarkToProcess.Add(benchmark, process.Id);
|
BenchmarkToProcess.Add(parameters.Benchmark, parameters.Process.Id);
|
||||||
StatsPerProcess.TryAdd(process.Id, GetInitializedStats(benchmark));
|
StatsPerProcess.TryAdd(parameters.Process.Id, GetInitializedStats(parameters));
|
||||||
|
|
||||||
Session = CreateSession(benchmark);
|
Session = CreateSession(parameters.Benchmark);
|
||||||
|
|
||||||
EnableProvider();
|
EnableProvider();
|
||||||
|
|
||||||
AttachToEvents(Session, benchmark);
|
AttachToEvents(Session, parameters.Benchmark);
|
||||||
|
|
||||||
// The ETW collection thread starts receiving events immediately, but we only
|
// The ETW collection thread starts receiving events immediately, but we only
|
||||||
// start aggregating them after ProcessStarted is called and we know which process
|
// start aggregating them after ProcessStarted is called and we know which process
|
||||||
|
@ -49,7 +50,7 @@ namespace BenchmarkDotNet.Diagnostics.Windows
|
||||||
WaitUntilStarted(task);
|
WaitUntilStarted(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual TStats GetInitializedStats(Benchmark benchmark) => new TStats();
|
protected virtual TStats GetInitializedStats(DiagnoserActionParameters parameters) => new TStats();
|
||||||
|
|
||||||
protected virtual TraceEventSession CreateSession(Benchmark benchmark)
|
protected virtual TraceEventSession CreateSession(Benchmark benchmark)
|
||||||
=> new TraceEventSession(GetSessionName(SessionNamePrefix, benchmark, benchmark.Parameters));
|
=> new TraceEventSession(GetSessionName(SessionNamePrefix, benchmark, benchmark.Parameters));
|
||||||
|
|
|
@ -19,11 +19,11 @@ namespace BenchmarkDotNet.Diagnostics.Windows
|
||||||
|
|
||||||
public IColumnProvider GetColumnProvider() => EmptyColumnProvider.Instance;
|
public IColumnProvider GetColumnProvider() => EmptyColumnProvider.Instance;
|
||||||
|
|
||||||
public void BeforeAnythingElse(Process process, Benchmark benchmark) => Start(process, benchmark);
|
public void BeforeAnythingElse(DiagnoserActionParameters parameters) => Start(parameters);
|
||||||
|
|
||||||
public void AfterSetup(Process process, Benchmark benchmark) { }
|
public void AfterSetup(DiagnoserActionParameters _) { }
|
||||||
|
|
||||||
public void BeforeMainRun(Process process, Benchmark benchmark) { }
|
public void BeforeMainRun(DiagnoserActionParameters _) { }
|
||||||
|
|
||||||
public void BeforeCleanup() => Stop();
|
public void BeforeCleanup() => Stop();
|
||||||
|
|
||||||
|
|
|
@ -30,11 +30,11 @@ namespace BenchmarkDotNet.Diagnostics.Windows
|
||||||
|
|
||||||
protected override string SessionNamePrefix => "GC";
|
protected override string SessionNamePrefix => "GC";
|
||||||
|
|
||||||
public void BeforeAnythingElse(Process process, Benchmark benchmark) { }
|
public void BeforeAnythingElse(DiagnoserActionParameters _) { }
|
||||||
|
|
||||||
public void AfterSetup(Process process, Benchmark benchmark) { }
|
public void AfterSetup(DiagnoserActionParameters _) { }
|
||||||
|
|
||||||
public void BeforeMainRun(Process process, Benchmark benchmark) => Start(process, benchmark);
|
public void BeforeMainRun(DiagnoserActionParameters parameters) => Start(parameters);
|
||||||
|
|
||||||
public void BeforeCleanup() => Stop();
|
public void BeforeCleanup() => Stop();
|
||||||
|
|
||||||
|
|
|
@ -112,10 +112,10 @@ namespace BenchmarkDotNet.Diagnostics.Windows
|
||||||
get { throw new NotImplementedException("Not needed for Kernel sessions (can be only one at a time"); }
|
get { throw new NotImplementedException("Not needed for Kernel sessions (can be only one at a time"); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public void BeforeAnythingElse(Process process, Benchmark benchmark) { }
|
public void BeforeAnythingElse(DiagnoserActionParameters _) { }
|
||||||
public void AfterSetup(Process process, Benchmark benchmark) { }
|
public void AfterSetup(DiagnoserActionParameters _) { }
|
||||||
|
|
||||||
public void BeforeMainRun(Process process, Benchmark benchmark) => Start(process, benchmark);
|
public void BeforeMainRun(DiagnoserActionParameters parameters) => Start(parameters);
|
||||||
|
|
||||||
public void BeforeCleanup() => Stop();
|
public void BeforeCleanup() => Stop();
|
||||||
|
|
||||||
|
@ -161,9 +161,9 @@ namespace BenchmarkDotNet.Diagnostics.Windows
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override PmcStats GetInitializedStats(Benchmark benchmark)
|
protected override PmcStats GetInitializedStats(DiagnoserActionParameters parameters)
|
||||||
{
|
{
|
||||||
var stats = new PmcStats(benchmark.Job.Diagnoser.HardwareCounters);
|
var stats = new PmcStats(parameters.Config.GetHardwareCounters().ToArray());
|
||||||
|
|
||||||
var counters = stats.Counters.Values;
|
var counters = stats.Counters.Values;
|
||||||
|
|
||||||
|
|
|
@ -371,12 +371,12 @@ namespace BenchmarkDotNet.IntegrationTests
|
||||||
var a = CharacteristicHelper
|
var a = CharacteristicHelper
|
||||||
.GetThisTypeCharacteristics(typeof(Job))
|
.GetThisTypeCharacteristics(typeof(Job))
|
||||||
.Select(c => c.Id);
|
.Select(c => c.Id);
|
||||||
Equal(string.Join(";", a), "Id;Accuracy;Diagnoser;Env;Infrastructure;Run");
|
Equal(string.Join(";", a), "Id;Accuracy;Env;Infrastructure;Run");
|
||||||
a = CharacteristicHelper
|
a = CharacteristicHelper
|
||||||
.GetAllCharacteristics(typeof(Job))
|
.GetAllCharacteristics(typeof(Job))
|
||||||
.Select(c => c.Id);
|
.Select(c => c.Id);
|
||||||
Equal(string.Join(";", a), "Id;Accuracy;AnalyzeLaunchVariance;EvaluateOverhead;" +
|
Equal(string.Join(";", a), "Id;Accuracy;AnalyzeLaunchVariance;EvaluateOverhead;" +
|
||||||
"MaxStdErrRelative;MinInvokeCount;MinIterationTime;RemoveOutliers;Diagnoser;HardwareCounters;Env;Affinity;" +
|
"MaxStdErrRelative;MinInvokeCount;MinIterationTime;RemoveOutliers;Env;Affinity;" +
|
||||||
"Jit;Platform;Runtime;Gc;AllowVeryLargeObjects;Concurrent;CpuGroups;Force;" +
|
"Jit;Platform;Runtime;Gc;AllowVeryLargeObjects;Concurrent;CpuGroups;Force;" +
|
||||||
"RetainVm;Server;Infrastructure;Clock;EngineFactory;Toolchain;Run;InvocationCount;IterationTime;" +
|
"RetainVm;Server;Infrastructure;Clock;EngineFactory;Toolchain;Run;InvocationCount;IterationTime;" +
|
||||||
"LaunchCount;RunStrategy;TargetCount;UnrollFactor;WarmupCount");
|
"LaunchCount;RunStrategy;TargetCount;UnrollFactor;WarmupCount");
|
||||||
|
|
|
@ -8,6 +8,7 @@ using BenchmarkDotNet.Loggers;
|
||||||
using BenchmarkDotNet.Running;
|
using BenchmarkDotNet.Running;
|
||||||
using BenchmarkDotNet.Tests.Loggers;
|
using BenchmarkDotNet.Tests.Loggers;
|
||||||
using BenchmarkDotNet.Toolchains;
|
using BenchmarkDotNet.Toolchains;
|
||||||
|
using BenchmarkDotNet.Toolchains.Parameters;
|
||||||
using BenchmarkDotNet.Toolchains.Results;
|
using BenchmarkDotNet.Toolchains.Results;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
using Xunit.Abstractions;
|
using Xunit.Abstractions;
|
||||||
|
@ -46,9 +47,9 @@ namespace BenchmarkDotNet.IntegrationTests
|
||||||
{
|
{
|
||||||
public bool Done { get; private set; }
|
public bool Done { get; private set; }
|
||||||
|
|
||||||
public ExecuteResult Execute(BuildResult buildResult, Benchmark benchmark, ILogger logger, IResolver resolver, IDiagnoser diagnoser)
|
public ExecuteResult Execute(ExecuteParameters executeParameters)
|
||||||
{
|
{
|
||||||
logger.WriteLine("Executing");
|
executeParameters.Logger.WriteLine("Executing");
|
||||||
Done = true;
|
Done = true;
|
||||||
return new ExecuteResult(true, 0, Array.Empty<string>(), Array.Empty<string>());
|
return new ExecuteResult(true, 0, Array.Empty<string>(), Array.Empty<string>());
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче