mirror of https://github.com/SixLabors/ImageSharp
2 changed files with 127 additions and 0 deletions
@ -0,0 +1,66 @@ |
|||||
|
using System.Numerics; |
||||
|
using System.Runtime.CompilerServices; |
||||
|
|
||||
|
using BenchmarkDotNet.Attributes; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Benchmarks.General.Vectorization |
||||
|
{ |
||||
|
public class UInt32ToSingle |
||||
|
{ |
||||
|
private float[] data; |
||||
|
|
||||
|
private const int Count = 64; |
||||
|
|
||||
|
[GlobalSetup] |
||||
|
public void Setup() |
||||
|
{ |
||||
|
this.data = new float[Count]; |
||||
|
} |
||||
|
|
||||
|
[Benchmark(Baseline = true)] |
||||
|
public void MagicMethod() |
||||
|
{ |
||||
|
ref Vector<float> b = ref Unsafe.As<float, Vector<float>>(ref this.data[0]); |
||||
|
|
||||
|
int n = Count / Vector<float>.Count; |
||||
|
|
||||
|
Vector<float> magick = new Vector<float>(32768.0f); |
||||
|
Vector<float> scale = new Vector<float>(255f) / new Vector<float>(256f); |
||||
|
|
||||
|
for (int i = 0; i < n; i++) |
||||
|
{ |
||||
|
// union { float f; uint32_t i; } u;
|
||||
|
// u.f = 32768.0f + x * (255.0f / 256.0f);
|
||||
|
// return (uint8_t)u.i;
|
||||
|
|
||||
|
ref Vector<float> d = ref Unsafe.Add(ref b, i); |
||||
|
Vector<float> x = d; |
||||
|
//x = Vector.Max(x, Vector<float>.Zero);
|
||||
|
//x = Vector.Min(x, Vector<float>.One);
|
||||
|
|
||||
|
x = (x * scale) + magick; |
||||
|
d = x; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
[Benchmark] |
||||
|
public void StandardSimd() |
||||
|
{ |
||||
|
int n = Count / Vector<float>.Count; |
||||
|
|
||||
|
ref Vector<float> b = ref Unsafe.As<float, Vector<float>>(ref this.data[0]); |
||||
|
|
||||
|
var scale = new Vector<float>(1f / 255f); |
||||
|
|
||||
|
for (int i = 0; i < n; i++) |
||||
|
{ |
||||
|
ref Vector<float> df = ref Unsafe.Add(ref b, i); |
||||
|
Vector<uint> du = Unsafe.As<Vector<float>, Vector<uint>>(ref df); |
||||
|
|
||||
|
Vector<float> v = Vector.ConvertToSingle(du); |
||||
|
v *= scale; |
||||
|
df = v; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,61 @@ |
|||||
|
using System.Numerics; |
||||
|
using System.Runtime.CompilerServices; |
||||
|
|
||||
|
using BenchmarkDotNet.Attributes; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Benchmarks.General.Vectorization |
||||
|
{ |
||||
|
public class WidenBytesToUInt32 |
||||
|
{ |
||||
|
private byte[] source; |
||||
|
|
||||
|
private uint[] dest; |
||||
|
|
||||
|
private const int Count = 64; |
||||
|
|
||||
|
[GlobalSetup] |
||||
|
public void Setup() |
||||
|
{ |
||||
|
this.source = new byte[Count]; |
||||
|
this.dest = new uint[Count]; |
||||
|
} |
||||
|
|
||||
|
[Benchmark(Baseline = true)] |
||||
|
public void Standard() |
||||
|
{ |
||||
|
const int N = Count / 8; |
||||
|
|
||||
|
ref SimdUtils.Octet.OfByte sBase = ref Unsafe.As<byte, SimdUtils.Octet.OfByte>(ref this.source[0]); |
||||
|
ref SimdUtils.Octet.OfUInt32 dBase = ref Unsafe.As<uint, SimdUtils.Octet.OfUInt32>(ref this.dest[0]); |
||||
|
|
||||
|
for (int i = 0; i < N; i++) |
||||
|
{ |
||||
|
Unsafe.Add(ref dBase, i).LoadFrom(ref Unsafe.Add(ref sBase, i)); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
[Benchmark] |
||||
|
public void Simd() |
||||
|
{ |
||||
|
int n = Count / Vector<byte>.Count; |
||||
|
|
||||
|
ref Vector<byte> sBase = ref Unsafe.As<byte, Vector<byte>>(ref this.source[0]); |
||||
|
ref Vector<uint> dBase = ref Unsafe.As<uint, Vector<uint>>(ref this.dest[0]); |
||||
|
|
||||
|
for (int i = 0; i < n; i++) |
||||
|
{ |
||||
|
Vector<byte> b = Unsafe.Add(ref sBase, i); |
||||
|
|
||||
|
Vector.Widen(b, out Vector<ushort> s0, out Vector<ushort> s1); |
||||
|
Vector.Widen(s0, out Vector<uint> w0, out Vector<uint> w1); |
||||
|
Vector.Widen(s1, out Vector<uint> w2, out Vector<uint> w3); |
||||
|
|
||||
|
ref Vector<uint> d = ref Unsafe.Add(ref dBase, i * 4); |
||||
|
d = w0; |
||||
|
Unsafe.Add(ref d, 1) = w1; |
||||
|
Unsafe.Add(ref d, 2) = w2; |
||||
|
Unsafe.Add(ref d, 3) = w3; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue