pass config from runner => executor => diagnoser #412

This commit is contained in:
Adam Sitnik 2017-04-07 19:53:56 +02:00
Родитель 43643ceda4
Коммит 303fff198c
19 изменённых файлов: 167 добавлений и 86 удалений

Просмотреть файл

@ -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>());
} }