using System.Numerics; using System.Runtime.CompilerServices; using BenchmarkDotNet.Attributes; namespace ImageSharp.Benchmarks.General.Vectorization { public abstract class SIMDBenchmarkBase where T : struct { protected T[] input; protected T[] result; protected T testValue; protected Vector testVector; protected virtual T GetTestValue() => default; protected virtual Vector GetTestVector() => new Vector(this.GetTestValue()); [Params(32)] public int InputSize { get; set; } [GlobalSetup] public virtual void Setup() { this.input = new T[this.InputSize]; this.result = new T[this.InputSize]; this.testValue = this.GetTestValue(); this.testVector = this.GetTestVector(); } public abstract class Multiply : SIMDBenchmarkBase { [Benchmark] public void Simd() { Vector v = this.testVector; for (int i = 0; i < this.input.Length; i += Vector.Count) { Vector a = Unsafe.As>(ref this.input[i]); a = a * v; Unsafe.As>(ref this.result[i]) = a; } } } public abstract class Divide : SIMDBenchmarkBase { [Benchmark] public void Simd() { Vector v = this.testVector; for (int i = 0; i < this.input.Length; i += Vector.Count) { Vector a = Unsafe.As>(ref this.input[i]); a = a / v; Unsafe.As>(ref this.result[i]) = a; } } } } }