Skip to content

Commit

Permalink
Add documentation for VS Profiler (#2672)
Browse files Browse the repository at this point in the history
* Add documentation for VS Profiler

- This change adds documentation for the Visual Studio profiler.
  There is a new document under features that explains how to use the
  nuget package and a new sample under IntroVisualStudioDiagnoser. A new
  package reference has also been added to the samples project to pull
  in the Visual Studio specific diagnosers for the sample project.

* Addressing PR feedback

---------

Co-authored-by: Nik Karpinsky <nikarpin@microsoft.com>
  • Loading branch information
karpinsn and Nik Karpinsky authored Dec 9, 2024
1 parent 5f0c47b commit 6367ad8
Show file tree
Hide file tree
Showing 8 changed files with 125 additions and 0 deletions.
2 changes: 2 additions & 0 deletions build/cSpell.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"Cygwin",
"Diagnoser",
"diagnosers",
"diagsession",
"disassemblers",
"disassm",
"Jits",
Expand All @@ -29,6 +30,7 @@
"Pseudocode",
"runtimes",
"Serilog",
"vsprofiler",
"vstest",
"Tailcall",
"toolchains",
Expand Down
2 changes: 2 additions & 0 deletions docs/articles/features/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,7 @@
href: etwprofiler.md
- name: EventPipeProfiler
href: event-pipe-profiler.md
- name: VSProfiler
href: vsprofiler.md
- name: VSTest
href: vstest.md
71 changes: 71 additions & 0 deletions docs/articles/features/vsprofiler.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
---
uid: docs.vsprofiler
name: VS Profiler
---

# Running with Visual Studio profiler
Visual Studio supports [profiler integration with BenchmarkDotNet](https://learn.microsoft.com/visualstudio/profiling/profiling-with-benchmark-dotnet) on Windows through its [Microsoft.VisualStudio.BenchmarkDotNetDiagnosers](https://www.nuget.org/packages/Microsoft.VisualStudio.DiagnosticsHub.BenchmarkDotNetDiagnosers) NuGet package. Once installed, Visual Studio specific diagnosers will capture performance data in runs and automatically open traces if launched through Visual Studio

![](../../images/vs-profiler-demo.png)

## How it works

First, install the [Microsoft.VisualStudio.BenchmarkDotNetDiagnosers](https://www.nuget.org/packages/Microsoft.VisualStudio.DiagnosticsHub.BenchmarkDotNetDiagnosers) NuGet package in your benchmarking project. Next add one or more of the Visual Studio diagnosers to your benchmark to capture the relevant profiling information while benchmarking. Lastly, run your benchmarks and a diagsession will be generated. If run from Visual Studio the diagsession will automatically be opened.

## Available Diagnosers

* `[CPUUsageDiagnoser]` - Enables the [CPU Usage tool](https://learn.microsoft.com/visualstudio/profiling/cpu-usage).
* `[DatabaseDiagnoser]` - Enables the [Database tool](https://learn.microsoft.com/visualstudio/profiling/analyze-database)
* `[DotNetCountersDiagnoser]` - Enables the [.NET Counters tool](https://learn.microsoft.com/visualstudio/profiling/dotnet-counters-tool)
* `[DotNetObjectAllocDiagnoser]` - Enables the [.NET Object Allocation tool](https://learn.microsoft.com/visualstudio/profiling/dotnet-alloc-tool). When using this tool, you must also specify `[DotNetObjectAllocJobConfiguration]` on the benchmark. If this is missing the run will fail and you will receive an error indicating you need to add it.
* `[EventsDiagnoser]` - Enables the [Events tool](https://learn.microsoft.com/visualstudio/profiling/events-viewer)
* `[FileIODiagnoser]` - Enables the [File IO tool](https://learn.microsoft.com/visualstudio/profiling/use-file-io)

## How to use it?

After installing the [Microsoft.VisualStudio.BenchmarkDotNetDiagnosers](https://www.nuget.org/packages/Microsoft.VisualStudio.DiagnosticsHub.BenchmarkDotNetDiagnosers) NuGet package add the following code as a benchmark:

```cs
using System;
using System.Security.Cryptography;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
using Microsoft.VSDiagnostics;

namespace MyBenchmarks
{
[CPUUsageDiagnoser]
public class Md5VsSha256
{
private const int N = 10000;
private readonly byte[] data;

private readonly SHA256 sha256 = SHA256.Create();
private readonly MD5 md5 = MD5.Create();

public Md5VsSha256()
{
data = new byte[N];
new Random(42).NextBytes(data);
}

[Benchmark]
public byte[] Sha256() => sha256.ComputeHash(data);

[Benchmark]
public byte[] Md5() => md5.ComputeHash(data);
}

public class Program
{
public static void Main(string[] args)
{
var summary = BenchmarkRunner.Run(typeof(Program).Assembly);
}
}
}
```

In this case we have added the `[CpuUsageDiagnoser]` to capture a CPU sampling trace. From here run the benchmark in Visual Studio (Ctrl+F5), and after the benchmark run the resulting diagsession will be displayed. Double clicking on one of the benchmark rows shown under the Benchmarks tab will filter the time selection to the specific benchmark allowing you to better isolate and investigate.

![](../../images/vs-profiler-demo.png)
23 changes: 23 additions & 0 deletions docs/articles/samples/IntroVisualStudioProfiler.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
uid: BenchmarkDotNet.Samples.IntroVisualStudioProfiler
---

## Sample: Visual Studio Profiler

Using the [Microsoft.VisualStudio.BenchmarkDotNetDiagnosers](https://www.nuget.org/packages/Microsoft.VisualStudio.DiagnosticsHub.BenchmarkDotNetDiagnosers) NuGet package you can capture performance profiles of your benchmarks that can be opened in Visual Studio.

### Source code

[!code-csharp[IntroVisualStudioDiagnoser.cs](../../../samples/BenchmarkDotNet.Samples/IntroVisualStudioDiagnoser.cs)]

### Output
The output will contain a path to the collected diagsession and automatically open in Visual Studio when launched from it.

```markdown
// * Diagnostic Output - VSDiagnosticsDiagnoser *
Collection result moved to 'C:\Work\BenchmarkDotNet\samples\BenchmarkDotNet.Samples\bin\Release\net8.0\BenchmarkDotNet.Artifacts\BenchmarkDotNet_IntroVisualStudioProfiler_20241205_192056.diagsession'.
Session : {d54ebddb-2d6d-404f-b1da-10acbc89635f}
Stopped
Exported diagsession file: C:\Work\BenchmarkDotNet\samples\BenchmarkDotNet.Samples\bin\Release\net8.0\BenchmarkDotNet.Artifacts\BenchmarkDotNet_IntroVisualStudioProfiler_20241205_192056.diagsession.
Opening diagsession in VisualStudio: 15296
```
2 changes: 2 additions & 0 deletions docs/articles/samples/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@
href: IntroTagColumn.md
- name: IntroTailcall
href: IntroTailcall.md
- name: IntroVisualStudioProfiler
href: IntroVisualStudioProfiler.md
- name: IntroWasm
href: IntroWasm.md
- name: IntroUnicode
Expand Down
Binary file added docs/images/vs-profiler-demo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
<PackageReference Include="System.Drawing.Common" Version="4.7.2" />
<!-- The Test SDK is required only for the VSTest Adapter to work -->
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.2" />
<!-- This package enables the Visual Studio Profiler integration IntroVisualStudioProfiler.cs -->
<PackageReference Include="Microsoft.VisualStudio.DiagnosticsHub.BenchmarkDotNetDiagnosers" Version="17.13.35606.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\BenchmarkDotNet.Diagnostics.dotTrace\BenchmarkDotNet.Diagnostics.dotTrace.csproj" />
Expand Down
23 changes: 23 additions & 0 deletions samples/BenchmarkDotNet.Samples/IntroVisualStudioDiagnoser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;
using BenchmarkDotNet.Attributes;
using Microsoft.VSDiagnostics;

namespace BenchmarkDotNet.Samples
{
// Enables profiling with the CPU Usage tool
// See: https://learn.microsoft.com/visualstudio/profiling/profiling-with-benchmark-dotnet
[CPUUsageDiagnoser]
public class IntroVisualStudioProfiler
{
private readonly Random rand = new Random(42);

[Benchmark]
public void BurnCPU()
{
for (int i = 0; i < 100000; ++i)
{
rand.Next(1, 100);
}
}
}
}

0 comments on commit 6367ad8

Please sign in to comment.