Skip to content

Commit

Permalink
Merge pull request #83 from msft-takend/main
Browse files Browse the repository at this point in the history
Dotnet 8 udpdate and Benchmarking
  • Loading branch information
swharden authored Nov 16, 2024
2 parents 5f8db20 + 8f33f3f commit 67a07e9
Show file tree
Hide file tree
Showing 14 changed files with 787 additions and 65 deletions.
24 changes: 24 additions & 0 deletions .github/workflows/benchmark.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Benchmark

on:
workflow_dispatch:
push:
branches:
- main

jobs:
benchmark:
name: Run Benchmarks
runs-on: windows-latest
strategy:
matrix:
dotnet-version: [8.x, 9.x]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{matrix.dotnet-version}}
dotnet-quality: "preview"
- name: Run benchmark
working-directory: src/FftSharp.Benchmark
run: dotnet run --exporters json --filter '*'
12 changes: 5 additions & 7 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,12 @@ jobs:
runs-on: windows-latest
steps:
- name: 🛒 Checkout
uses: actions/checkout@v3
- name: ✨ Setup .NET 6
uses: actions/setup-dotnet@v3
with:
dotnet-version: "6.0.x"
uses: actions/checkout@v4
- name: ✨ Setup .NET
uses: actions/setup-dotnet@v4
- name: 🚚 Restore
run: dotnet restore src
- name: 🛠️ Build
run: dotnet build src --configuration Release --no-restore
run: dotnet build src
- name: 🧪 Test
run: dotnet test src --configuration Release --no-build
run: dotnet test src
24 changes: 7 additions & 17 deletions .github/workflows/package.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,20 @@ jobs:
runs-on: windows-latest
steps:
- name: 🛒 Checkout
uses: actions/checkout@v3
- name: ✨ Setup .NET 6
uses: actions/setup-dotnet@v3
with:
dotnet-version: "6.0.x"
uses: actions/checkout@v4
- name: ✨ Setup .NET
uses: actions/setup-dotnet@v4
- name: 🚚 Restore
run: dotnet restore src
- name: 🛠️ Build
run: dotnet build src --configuration Release --no-restore
run: dotnet build src
- name: 🧪 Test
run: dotnet test src --configuration Release --no-build
run: dotnet test src
- name: 📦 Pack
run: dotnet pack src --configuration Release --no-build
- name: 💾 Store
uses: actions/upload-artifact@v2
with:
name: Packages
retention-days: 1
path: |
src/FftSharp/bin/Release/*.nupkg
src/FftSharp/bin/Release/*.snupkg
run: dotnet pack src
- name: 🔑 Secret
uses: nuget/setup-nuget@v1
with:
nuget-api-key: ${{ secrets.NUGET_API_KEY }}
- name: 🚀 Deploy
run: nuget push "src\FftSharp\bin\Release\*.nupkg" -SkipDuplicate -Source https://api.nuget.org/v3/index.json
run: nuget push "src\FftSharp\bin\Release\*.nupkg" -SkipDuplicate -Source https://api.nuget.org/v3/index.json
17 changes: 17 additions & 0 deletions src/FftSharp.Benchmark/BenchmarkLoadData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace FftSharp.Benchmark;

public static class BenchmarkLoadData
{
public static double[] Double(string fileName) =>
File.ReadLines(fileName)
.Where(x => !x.StartsWith('#') && x.Length > 1)
.Select(x => double.Parse(x))
.ToArray();

public static System.Numerics.Complex[] Complex(string fileName) =>
File.ReadLines(fileName)
.Select(x => x.Trim('(').Trim(')').Trim('j'))
.Select(x => x.Replace("-", " -").Replace("+", " +").Trim())
.Select(x => new System.Numerics.Complex(double.Parse(x.Split(' ')[0]), double.Parse(x.Split(' ')[1])))
.ToArray();
}
49 changes: 49 additions & 0 deletions src/FftSharp.Benchmark/Benchmarking.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Benchmarking

## Benchmarking FFTSharp

To run the benchmarks navigate to the `src/FftSharp.Benchmark` directory and run the following command:

```bash
dotnet run -c Release
```

## Results 12/20/2023

### BluesteinSizeBenchmark
```
BenchmarkDotNet v0.13.11, Windows 11 (10.0.22631.2861/23H2/2023Update/SunValley3)
Intel Core i7-1065G7 CPU 1.30GHz, 1 CPU, 8 logical and 4 physical cores
.NET SDK 8.0.100
[Host] : .NET 6.0.25 (6.0.2523.51912), X64 RyuJIT AVX2
.NET 6.0 : .NET 6.0.25 (6.0.2523.51912), X64 RyuJIT AVX2
.NET 8.0 : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX-512F+CD+BW+DQ+VL+VBMI
```
| Method | Job | Runtime | DataLength | Mean | Error | StdDev | Gen0 | Gen1 | Gen2 | Allocated |
|---------- |--------- |--------- |----------- |-------------:|-------------:|-------------:|---------:|---------:|---------:|------------:|
| **Bluestein** | **.NET 6.0** | **.NET 6.0** | **100** | **26.40 μs** | **0.401 μs** | **0.375 μs** | **7.1716** | **0.0305** | **-** | **29.36 KB** |
| Bluestein | .NET 8.0 | .NET 8.0 | 100 | 24.97 μs | 0.321 μs | 0.284 μs | 7.1716 | - | - | 29.36 KB |
| **Bluestein** | **.NET 6.0** | **.NET 6.0** | **1000** | **247.14 μs** | **3.809 μs** | **3.181 μs** | **58.1055** | **16.1133** | **-** | **239.49 KB** |
| Bluestein | .NET 8.0 | .NET 8.0 | 1000 | 239.35 μs | 4.046 μs | 3.379 μs | 58.1055 | 16.3574 | - | 239.49 KB |
| **Bluestein** | **.NET 6.0** | **.NET 6.0** | **10000** | **5,426.03 μs** | **88.896 μs** | **102.372 μs** | **984.3750** | **984.3750** | **984.3750** | **3641.08 KB** |
| Bluestein | .NET 8.0 | .NET 8.0 | 10000 | 5,348.21 μs | 103.018 μs | 86.025 μs | 984.3750 | 984.3750 | 984.3750 | 3641.04 KB |
| **Bluestein** | **.NET 6.0** | **.NET 6.0** | **100000** | **84,122.15 μs** | **1,655.385 μs** | **2,374.104 μs** | **833.3333** | **833.3333** | **833.3333** | **29749.57 KB** |
| Bluestein | .NET 8.0 | .NET 8.0 | 100000 | 83,047.50 μs | 1,654.760 μs | 2,718.818 μs | 666.6667 | 666.6667 | 666.6667 | 29751.45 KB |

### FftBenchmark
```
BenchmarkDotNet v0.13.11, Windows 11 (10.0.22631.2861/23H2/2023Update/SunValley3)
Intel Core i7-1065G7 CPU 1.30GHz, 1 CPU, 8 logical and 4 physical cores
.NET SDK 8.0.100
[Host] : .NET 6.0.25 (6.0.2523.51912), X64 RyuJIT AVX2
.NET 6.0 : .NET 6.0.25 (6.0.2523.51912), X64 RyuJIT AVX2
.NET 8.0 : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX-512F+CD+BW+DQ+VL+VBMI
```
| Method | Job | Runtime | Mean | Error | StdDev | Gen0 | Gen1 | Allocated |
|------------------------ |--------- |--------- |----------:|---------:|---------:|--------:|--------:|----------:|
| FFT_Forward | .NET 6.0 | .NET 6.0 | 41.47 μs | 0.722 μs | 0.676 μs | 1.9531 | - | 8.02 KB |
| FFT_ForwardReal | .NET 6.0 | .NET 6.0 | 42.72 μs | 0.715 μs | 0.669 μs | 2.9297 | - | 12.06 KB |
| FFT_BluesteinComparason | .NET 6.0 | .NET 6.0 | 233.21 μs | 3.444 μs | 3.053 μs | 54.4434 | 15.3809 | 224.24 KB |
| FFT_Forward | .NET 8.0 | .NET 8.0 | 41.08 μs | 0.749 μs | 0.585 μs | 1.9531 | - | 8.02 KB |
| FFT_ForwardReal | .NET 8.0 | .NET 8.0 | 41.79 μs | 0.788 μs | 0.698 μs | 2.9297 | - | 12.06 KB |
| FFT_BluesteinComparason | .NET 8.0 | .NET 8.0 | 223.61 μs | 4.330 μs | 4.633 μs | 54.4434 | 15.3809 | 224.23 KB |
34 changes: 34 additions & 0 deletions src/FftSharp.Benchmark/BluesteinSizeBenchmark.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Jobs;
using MathNet.Numerics;
namespace FftSharp.Benchmark;

[MemoryDiagnoser]
[SimpleJob(RuntimeMoniker.Net60)]
[SimpleJob(RuntimeMoniker.Net80)]
public class BluesteinSizeBenchmark
{
private double[] Sample;
[Params(100, 1000, 10_000, 100_000)]
public int DataLength { get ; set; }
public double Frequency = 60;
public double SampleRate = 1000;

[GlobalSetup]
public void BluesteinSizeBenchmarkSetup()
{
this.Sample = Generate.Sinusoidal(this.DataLength, this.SampleRate, this.Frequency, 1);
if(this.Sample.Length != this.DataLength)
{
throw new Exception("Sample length does not match DataLength");
}
}

[Benchmark]
public void Bluestein()
{
var something = Experimental.Bluestein(this.Sample);

Check warning on line 30 in src/FftSharp.Benchmark/BluesteinSizeBenchmark.cs

View workflow job for this annotation

GitHub Actions / Build and Test

'Experimental' is obsolete: 'This module is for educational purposes only'

Check warning on line 30 in src/FftSharp.Benchmark/BluesteinSizeBenchmark.cs

View workflow job for this annotation

GitHub Actions / Build and Test

'Experimental' is obsolete: 'This module is for educational purposes only'

Check warning on line 30 in src/FftSharp.Benchmark/BluesteinSizeBenchmark.cs

View workflow job for this annotation

GitHub Actions / Run Benchmarks (8.x)

'Experimental' is obsolete: 'This module is for educational purposes only'

Check warning on line 30 in src/FftSharp.Benchmark/BluesteinSizeBenchmark.cs

View workflow job for this annotation

GitHub Actions / Run Benchmarks (9.x)

'Experimental' is obsolete: 'This module is for educational purposes only'
}

}

36 changes: 36 additions & 0 deletions src/FftSharp.Benchmark/FftBenchmark.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Jobs;

namespace FftSharp.Benchmark;
[SimpleJob(RuntimeMoniker.Net60)]
[SimpleJob(RuntimeMoniker.Net80)]
[MemoryDiagnoser]
public class FftBenchmark
{
private double[] Sample;

[GlobalSetup]
public void FftBenchmarkSetup()
{
this.Sample = BenchmarkLoadData.Double("sample.txt");
}

[Benchmark]
public void FFT_Forward()
{
var something = FFT.Forward(this.Sample);
}

[Benchmark]
public void FFT_ForwardReal()
{
var something = FFT.ForwardReal(this.Sample);
}

[Benchmark]
public void FFT_BluesteinComparason()
{
var something = Experimental.Bluestein(this.Sample);

Check warning on line 33 in src/FftSharp.Benchmark/FftBenchmark.cs

View workflow job for this annotation

GitHub Actions / Build and Test

'Experimental' is obsolete: 'This module is for educational purposes only'

Check warning on line 33 in src/FftSharp.Benchmark/FftBenchmark.cs

View workflow job for this annotation

GitHub Actions / Build and Test

'Experimental' is obsolete: 'This module is for educational purposes only'

Check warning on line 33 in src/FftSharp.Benchmark/FftBenchmark.cs

View workflow job for this annotation

GitHub Actions / Run Benchmarks (8.x)

'Experimental' is obsolete: 'This module is for educational purposes only'

Check warning on line 33 in src/FftSharp.Benchmark/FftBenchmark.cs

View workflow job for this annotation

GitHub Actions / Run Benchmarks (9.x)

'Experimental' is obsolete: 'This module is for educational purposes only'
}
}

29 changes: 29 additions & 0 deletions src/FftSharp.Benchmark/FftSharp.Benchmark.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<NoWarn>$(NoWarn);CA1018;CA5351;CA1825;CA8618</NoWarn>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.13.11" />
<PackageReference Include="BenchmarkDotNet.Annotations" Version="0.13.11" />
<PackageReference Include="MathNet.Numerics" Version="5.0.0" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFrameworkIdentifier)' == '.NETFramework' ">
<Reference Include="System.Reflection" />
<PackageReference Include="System.Memory" Version="4.5.5" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\FftSharp\FftSharp.csproj" />
</ItemGroup>

<ItemGroup>
<None Update="sample.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
16 changes: 16 additions & 0 deletions src/FftSharp.Benchmark/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Environments;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Running;

namespace FftSharp.Benchmark;

public class Program
{
static void Main(string[] args)
{
Console.WriteLine("FftSharp Benchmarks!");
BenchmarkRunner.Run<FftBenchmark>();
BenchmarkRunner.Run<BluesteinSizeBenchmark>();
}
}
Loading

0 comments on commit 67a07e9

Please sign in to comment.