// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Columns;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Jobs;
using SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
namespace SixLabors.ImageSharp.Benchmarks.Codecs.Heif;
///
/// Measures the production AV1 forward-transform pipeline at the runtime's selected vector width.
///
[Config(typeof(Configuration))]
[MemoryDiagnoser(displayGenColumns: false)]
[GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)]
[CategoriesColumn]
public class Av1TransformBenchmarks
{
private readonly short[] spatial = new short[64 * 64];
private readonly int[] coefficients = new int[32 * 32];
private readonly int[] workspace = new int[Av1TransformWorkspace.MaximumLength];
///
/// Gets or sets the coded sample bit depth used by the transform.
///
[Params(8, 12)]
public int BitDepth { get; set; }
///
/// Initializes deterministic residual data outside the measured operations.
///
[GlobalSetup]
public void Setup()
{
for (int index = 0; index < this.spatial.Length; index++)
{
this.spatial[index] = (short)(((index * 73) % 511) - 255);
}
}
///
/// Measures an eight-by-eight forward DCT block.
///
/// The last coefficient written by the transform.
[Benchmark]
[BenchmarkCategory("Forward8x8")]
public int Forward8x8()
{
Av1ForwardTransformer.Transform2d(
this.spatial,
this.coefficients,
8,
Av1TransformType.DctDct,
Av1TransformSize.Size8x8,
this.BitDepth,
this.workspace);
return this.coefficients[63];
}
///
/// Measures a thirty-two-by-thirty-two forward DCT block.
///
/// The last coefficient written by the transform.
[Benchmark]
[BenchmarkCategory("Forward32x32")]
public int Forward32x32()
{
Av1ForwardTransformer.Transform2d(
this.spatial,
this.coefficients,
32,
Av1TransformType.DctDct,
Av1TransformSize.Size32x32,
this.BitDepth,
this.workspace);
return this.coefficients[^1];
}
///
/// Measures the packed-to-expanded boundary of a thirty-two-by-sixty-four forward DCT block.
///
/// The last coded coefficient written by the transform.
[Benchmark]
[BenchmarkCategory("Forward32x64")]
public int Forward32x64()
{
Av1ForwardTransformer.Transform2d(
this.spatial,
this.coefficients,
32,
Av1TransformType.DctDct,
Av1TransformSize.Size32x64,
this.BitDepth,
this.workspace);
return this.coefficients[^1];
}
///
/// Measures a sixty-four-by-sixty-four forward DCT block with the normative coefficient truncation.
///
/// The last coded coefficient written by the transform.
[Benchmark]
[BenchmarkCategory("Forward64x64")]
public int Forward64x64()
{
Av1ForwardTransformer.Transform2d(
this.spatial,
this.coefficients,
64,
Av1TransformType.DctDct,
Av1TransformSize.Size64x64,
this.BitDepth,
this.workspace);
return this.coefficients[^1];
}
///
/// Configures separate production-process measurements for preferred 256-bit and 512-bit vectors.
///
public sealed class Configuration : ManualConfig
{
///
/// Initializes a new instance of the class.
///
public Configuration()
{
this.AddJob(
Job.ShortRun
.WithId("Vector256")
.WithEnvironmentVariable("DOTNET_PreferredVectorBitWidth", "256")
.WithEnvironmentVariable("COMPlus_PreferredVectorBitWidth", "256")
.AsBaseline());
this.AddJob(
Job.ShortRun
.WithId("Vector512")
.WithEnvironmentVariable("DOTNET_PreferredVectorBitWidth", "512")
.WithEnvironmentVariable("COMPlus_PreferredVectorBitWidth", "512"));
}
}
}