Browse Source

Remove SSE2 version of VectorMismatch: Profiling does not show any speedup

pull/1849/head
Brian Popow 5 years ago
parent
commit
c174ab42be
  1. 63
      src/ImageSharp/Formats/Webp/Lossless/LosslessUtils.cs
  2. 28
      tests/ImageSharp.Tests/Formats/WebP/LosslessUtilsTests.cs

63
src/ImageSharp/Formats/Webp/Lossless/LosslessUtils.cs

@ -83,69 +83,12 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
ref uint array1Ref = ref MemoryMarshal.GetReference(array1);
ref uint array2Ref = ref MemoryMarshal.GetReference(array2);
#if SUPPORTS_RUNTIME_INTRINSICS
if (Sse2.IsSupported)
while (matchLen < length && Unsafe.Add(ref array1Ref, matchLen) == Unsafe.Add(ref array2Ref, matchLen))
{
if (length >= 12)
{
Vector128<uint> a0 = Unsafe.As<uint, Vector128<uint>>(ref array1Ref);
Vector128<uint> a1 = Unsafe.As<uint, Vector128<uint>>(ref array2Ref);
do
{
// Loop unrolling and early load both provide a speedup.
Vector128<uint> cmpA = Sse2.CompareEqual(a0, a1);
Vector128<uint> b0 = Unsafe.As<uint, Vector128<uint>>(ref Unsafe.Add(ref array1Ref, matchLen + 4));
Vector128<uint> b1 = Unsafe.As<uint, Vector128<uint>>(ref Unsafe.Add(ref array2Ref, matchLen + 4));
if (Sse2.MoveMask(cmpA.AsByte()) != 0xffff)
{
break;
}
matchLen += 4;
Vector128<uint> cmpB = Sse2.CompareEqual(b0, b1);
a0 = Unsafe.As<uint, Vector128<uint>>(ref Unsafe.Add(ref array1Ref, matchLen + 4));
a1 = Unsafe.As<uint, Vector128<uint>>(ref Unsafe.Add(ref array2Ref, matchLen + 4));
if (Sse2.MoveMask(cmpB.AsByte()) != 0xffff)
{
break;
}
matchLen += 4;
}
while (matchLen + 12 < length);
}
else
{
// Unroll the potential first two loops.
if (length >= 4
&& Sse2.MoveMask(
Sse2.CompareEqual(
Unsafe.As<uint, Vector128<uint>>(ref array1Ref),
Unsafe.As<uint, Vector128<uint>>(ref array2Ref)).AsByte()) == 0xffff)
{
matchLen = 4;
if (length >= 8
&& Sse2.MoveMask(
Sse2.CompareEqual(
Unsafe.As<uint, Vector128<uint>>(ref Unsafe.Add(ref array1Ref, 4)),
Unsafe.As<uint, Vector128<uint>>(ref Unsafe.Add(ref array2Ref, 4))).AsByte()) == 0xffff)
{
matchLen = 8;
}
}
}
matchLen++;
}
#endif
{
while (matchLen < length && Unsafe.Add(ref array1Ref, matchLen) == Unsafe.Add(ref array2Ref, matchLen))
{
matchLen++;
}
return matchLen;
}
return matchLen;
}
[MethodImpl(InliningOptions.ShortMethod)]

28
tests/ImageSharp.Tests/Formats/WebP/LosslessUtilsTests.cs

@ -10,24 +10,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp
[Trait("Format", "Webp")]
public class LosslessUtilsTests
{
private static void RunVectorMismatchTest()
{
uint[] array1 = { 4278193152, 4278192896, 4278192896, 4278192896, 4278192896, 4278192896, 4278192896, 4278192896, 4278192896, 4278192896, 4278192896, 4278192896, 4278192896, 4278192896, 4278192896, 4278192896, 4278192896, 4278192896, 4278192896 };
uint[] array2 = { 4278193152, 4278192896, 4278192896, 4278192896, 4278192896, 4278192896, 4278192896, 4278192896, 4278192896, 4278192896, 4278192896, 4278192896, 4278192896, 4278192896, 4278192896, 4278192896, 4278192896, 4278192896, 4278192896 };
int expected1 = 18;
// Test unroll first two loops path also.
uint[] array3 = { 4279238656, 4278714368, 4279238656, 4279238656, 4279238656, 4279238656, 4279238896, 4279238896, 4279238884 };
uint[] array4 = { 4279238656, 4278714368, 4279238656, 4279238656, 4278190080, 4278190080, 4278190080, 4278190080, 4278190080 };
int expected2 = 4;
int actual1 = LosslessUtils.VectorMismatch(array1, array2, 18);
int actual2 = LosslessUtils.VectorMismatch(array3, array4, 9);
Assert.Equal(expected1, actual1);
Assert.Equal(expected2, actual2);
}
private static void RunSubtractGreenTest()
{
uint[] pixelData =
@ -211,9 +193,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp
}
}
[Fact]
public void VectorMismatch_Works() => RunVectorMismatchTest();
[Fact]
public void Predictor11_Works() => RunPredictor11Test();
@ -236,12 +215,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp
public void TransformColorInverse_Works() => RunTransformColorInverseTest();
#if SUPPORTS_RUNTIME_INTRINSICS
[Fact]
public void VectorMismatch_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunVectorMismatchTest, HwIntrinsics.AllowAll);
[Fact]
public void VectorMismatch_WithoutSSE2_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunVectorMismatchTest, HwIntrinsics.DisableSSE2);
[Fact]
public void Predictor11_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunPredictor11Test, HwIntrinsics.AllowAll);

Loading…
Cancel
Save