Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Adler32 to correctly filter intrinsics. #1229

Merged
merged 3 commits into from
Jun 15, 2020
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/ImageSharp/Formats/Png/Zlib/Adler32.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public static uint Calculate(uint adler, ReadOnlySpan<byte> buffer)
}

#if SUPPORTS_RUNTIME_INTRINSICS
if (Sse3.IsSupported && buffer.Length >= MinBufferSize)
if (Ssse3.IsSupported && buffer.Length >= MinBufferSize)
{
return CalculateSse(adler, buffer);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also rename CalculateSse to CalculateSsse?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would say no. It’s still an iteration of SSE technology.

}
Expand Down
48 changes: 47 additions & 1 deletion tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,19 @@
// Licensed under the Apache License, Version 2.0.

// ReSharper disable InconsistentNaming
using System.Diagnostics;
using System.IO;
using System.Linq;

#if SUPPORTS_RUNTIME_INTRINSICS
using System.Runtime.Intrinsics.X86;
#endif
using Microsoft.DotNet.RemoteExecutor;
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.Metadata;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing.Processors.Quantization;
using SixLabors.ImageSharp.Tests.TestUtilities;
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;

using Xunit;
Expand Down Expand Up @@ -529,6 +534,47 @@ public void Encode_WorksWithDiscontiguousBuffers<TPixel>(TestImageProvider<TPixe
}
}

[Theory]
[WithTestPatternImages(100, 100, PixelTypes.Rgba32)]
public void EncodeWorksWithoutSsse3Intrinsics<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
static void RunTest(string providerDump)
{
TestImageProvider<TPixel> provider =
BasicSerializer.Deserialize<TestImageProvider<TPixel>>(providerDump);
#if SUPPORTS_RUNTIME_INTRINSICS
Assert.False(Ssse3.IsSupported);
#endif

foreach (PngInterlaceMode interlaceMode in InterlaceMode)
{
TestPngEncoderCore(
provider,
PngColorType.Rgb,
PngFilterMethod.Adaptive,
PngBitDepth.Bit8,
interlaceMode,
appendPixelType: true,
appendPngColorType: true);
}
}

string providerDump = BasicSerializer.Serialize(provider);

var processStartInfo = new ProcessStartInfo();
processStartInfo.Environment[TestEnvironment.Features.EnableSSE3] = TestEnvironment.Features.Off;

RemoteExecutor.Invoke(
RunTest,
providerDump,
new RemoteInvokeOptions
{
StartInfo = processStartInfo
})
.Dispose();
}

private static void TestPngEncoderCore<TPixel>(
TestImageProvider<TPixel> provider,
PngColorType pngColorType,
Expand Down
34 changes: 34 additions & 0 deletions tests/ImageSharp.Tests/TestUtilities/TestEnvironment.Features.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.

namespace SixLabors.ImageSharp.Tests
{
public static partial class TestEnvironment
{
internal static class Features
{
public const string On = "1";
public const string Off = "0";

public const string EnableAES = "COMPlus_EnableAES";
public const string EnableAVX = "COMPlus_EnableAVX";
public const string EnableAVX2 = "COMPlus_EnableAVX2";
public const string EnableBMI1 = "COMPlus_EnableBMI1";
public const string EnableBMI2 = "COMPlus_EnableBMI2";
public const string EnableFMA = "COMPlus_EnableFMA";
public const string EnableHWIntrinsic = "COMPlus_EnableHWIntrinsic";
public const string EnableIncompleteISAClass = "COMPlus_EnableIncompleteISAClass";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one isn't a production switch.

For the others, there is a rough hierarchy they follow:

  • EnableHWIntrinsic
    • EnableSSE
      • EnableSSE2
        • EnableAES
        • EnablePCLMULQDQ
        • EnableSSE3
          • EnableSSSE3
            • EnableSSE41
              • EnableSSE42
                • EnablePOPCNT
                • EnableAVX
                  • EnableFMA
                  • EnableAVX2
    • EnableBMI1
    • EnableBMI2
    • EnableLZCNT

FeatureSIMD ends up impacting all SIMD support (including System.Numerics) but not things like LZCNT, BMI1, or BMI2
EnableSSE3_4 is a legacy switch that exists for compat and is basically the same as EnableSSE3

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The hierarchy basically means disabling SSE (EnableSSE=0) will also disable everything below it

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah lovely. I'll reference that. I intend on doing more intrinsics work in the near future.

public const string EnableLZCNT = "COMPlus_EnableLZCNT";
public const string EnablePCLMULQDQ = "COMPlus_EnablePCLMULQDQ";
public const string EnablePOPCNT = "COMPlus_EnablePOPCNT";
public const string EnableSSE = "COMPlus_EnableSSE";
public const string EnableSSE2 = "COMPlus_EnableSSE2";
public const string EnableSSE3 = "COMPlus_EnableSSE3";
public const string EnableSSE3_4 = "COMPlus_EnableSSE3_4";
public const string EnableSSE41 = "COMPlus_EnableSSE41";
public const string EnableSSE42 = "COMPlus_EnableSSE42";
public const string EnableSSSE3 = "COMPlus_EnableSSSE3";
public const string FeatureSIMD = "COMPlus_FeatureSIMD";
}
}
}