// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. namespace SixLabors.ImageSharp.Benchmarks.General.Vectorization; using System; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using BenchmarkDotNet.Attributes; /// /// This benchmark compares different methods for fetching memory data into /// checking if JIT has limitations. Normally SIMD acceleration should be here for all methods. /// public class VectorFetching { private float testValue; private float[] data; [Params(64)] public int InputSize { get; set; } [GlobalSetup] public void Setup() { this.data = new float[this.InputSize]; this.testValue = 42; for (int i = 0; i < this.InputSize; i++) { this.data[i] = i; } } [Benchmark(Baseline = true)] public void Baseline() { float v = this.testValue; for (int i = 0; i < this.data.Length; i++) { this.data[i] = this.data[i] * v; } } [Benchmark] public void FetchWithVectorConstructor() { Vector v = new(this.testValue); for (int i = 0; i < this.data.Length; i += Vector.Count) { Vector a = new(this.data, i); a = a * v; a.CopyTo(this.data, i); } } [Benchmark] public void FetchWithUnsafeCast() { Vector v = new(this.testValue); ref Vector start = ref Unsafe.As>(ref this.data[0]); nuint n = (uint)this.InputSize / (uint)Vector.Count; for (nuint i = 0; i < n; i++) { ref Vector p = ref Unsafe.Add(ref start, i); Vector a = p; a *= v; p = a; } } [Benchmark] public void FetchWithUnsafeCastNoTempVector() { Vector v = new(this.testValue); ref Vector start = ref Unsafe.As>(ref this.data[0]); nuint n = (uint)this.InputSize / (uint)Vector.Count; for (nuint i = 0; i < n; i++) { ref Vector a = ref Unsafe.Add(ref start, i); a *= v; } } [Benchmark] public void FetchWithUnsafeCastFromReference() { Vector v = new(this.testValue); Span span = new(this.data); ref Vector start = ref Unsafe.As>(ref MemoryMarshal.GetReference(span)); nuint n = (uint)this.InputSize / (uint)Vector.Count; for (nuint i = 0; i < n; i++) { ref Vector a = ref Unsafe.Add(ref start, i); a *= v; } } }