// 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")); } } }