Created
December 6, 2021 04:21
-
-
Save MarkPflug/55173728458020c6d335cc099c891c0b to your computer and use it in GitHub Desktop.
BenchmarkDotNet CPU utilization
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using BenchmarkDotNet.Analysers; | |
using BenchmarkDotNet.Columns; | |
using BenchmarkDotNet.Configs; | |
using BenchmarkDotNet.Diagnosers; | |
using BenchmarkDotNet.Engines; | |
using BenchmarkDotNet.Exporters; | |
using BenchmarkDotNet.Loggers; | |
using BenchmarkDotNet.Reports; | |
using BenchmarkDotNet.Running; | |
using BenchmarkDotNet.Validators; | |
using System; | |
using System.Collections.Generic; | |
using System.Diagnostics; | |
namespace Benchmarks | |
{ | |
public class CpuDiagnoserAttribute : Attribute, IConfigSource | |
{ | |
public IConfig Config { get; } | |
public CpuDiagnoserAttribute() | |
{ | |
Config = ManualConfig.CreateEmpty().AddDiagnoser(new CpuDiagnoser()); | |
} | |
} | |
public class CpuDiagnoser : IDiagnoser | |
{ | |
Process proc; | |
public CpuDiagnoser() | |
{ | |
this.proc = Process.GetCurrentProcess(); | |
} | |
public IEnumerable<string> Ids => new[] { "CPU" }; | |
public IEnumerable<IExporter> Exporters => Array.Empty<IExporter>(); | |
public IEnumerable<IAnalyser> Analysers => Array.Empty<IAnalyser>(); | |
public void DisplayResults(ILogger logger) | |
{ | |
} | |
public RunMode GetRunMode(BenchmarkCase benchmarkCase) | |
{ | |
return RunMode.NoOverhead; | |
} | |
long userStart, userEnd; | |
long privStart, privEnd; | |
public void Handle(HostSignal signal, DiagnoserActionParameters parameters) | |
{ | |
if(signal == HostSignal.BeforeActualRun) | |
{ | |
userStart = proc.UserProcessorTime.Ticks; | |
privStart = proc.PrivilegedProcessorTime.Ticks; | |
} | |
if(signal == HostSignal.AfterActualRun) | |
{ | |
userEnd = proc.UserProcessorTime.Ticks; | |
privEnd = proc.PrivilegedProcessorTime.Ticks; | |
} | |
} | |
public IEnumerable<Metric> ProcessResults(DiagnoserResults results) | |
{ | |
yield return new Metric(CpuUserMetricDescriptor.Instance, (userEnd - userStart) * 100d / results.TotalOperations); | |
yield return new Metric(CpuPrivilegedMetricDescriptor.Instance, (privEnd - privStart) * 100d / results.TotalOperations); | |
} | |
public IEnumerable<ValidationError> Validate(ValidationParameters validationParameters) | |
{ | |
yield break; | |
} | |
class CpuUserMetricDescriptor : IMetricDescriptor | |
{ | |
internal static readonly IMetricDescriptor Instance = new CpuUserMetricDescriptor(); | |
public string Id => "CPU User Time"; | |
public string DisplayName => Id; | |
public string Legend => Id; | |
public string NumberFormat => "0.##"; | |
public UnitType UnitType => UnitType.Time; | |
public string Unit => "ns"; | |
public bool TheGreaterTheBetter => false; | |
public int PriorityInCategory => 1; | |
} | |
class CpuPrivilegedMetricDescriptor : IMetricDescriptor | |
{ | |
internal static readonly IMetricDescriptor Instance = new CpuPrivilegedMetricDescriptor(); | |
public string Id => "CPU Privileged Time"; | |
public string DisplayName => Id; | |
public string Legend => Id; | |
public string NumberFormat => "0.##"; | |
public UnitType UnitType => UnitType.Time; | |
public string Unit => "ns"; | |
public bool TheGreaterTheBetter => false; | |
public int PriorityInCategory => 1; | |
} | |
} | |
} |
Thanks for the swift response! Okay, got it, very strange. And fyi, this seems to also affect .NET 6, so maybe it is more because of a change in how benchmarkdotnet spins up the processes or something like that? 🤷
Got it working under .NET 8:
- Add [InProcess] on the class with the bechmarks.
- You might have to run it with Administrator - sorry, too lazy to restart and check if it works without.
- Start Without Debugger to get best results.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
No idea, sorry. Seems that something in .net 7 broke it. I noticed this too and stopped using it for my benchmarks.