diff --git a/src/ImageSharp/Common/Helpers/Numerics.cs b/src/ImageSharp/Common/Helpers/Numerics.cs index fc6cfd585a..f2f9aaad2c 100644 --- a/src/ImageSharp/Common/Helpers/Numerics.cs +++ b/src/ImageSharp/Common/Helpers/Numerics.cs @@ -5,6 +5,7 @@ using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.Arm; using System.Runtime.Intrinsics.X86; namespace SixLabors.ImageSharp; @@ -808,6 +809,19 @@ internal static class Numerics return Sse2.ConvertToInt32(vsum); } + /// + /// Reduces elements of the vector into one sum. + /// + /// The accumulator to reduce. + /// The sum of all elements. + [MethodImpl(InliningOptions.ShortMethod)] + public static int ReduceSumArm(Vector128 accumulator) + { + Vector128 sum2 = AdvSimd.AddPairwiseWidening(accumulator); + Vector64 sum3 = AdvSimd.Add(sum2.GetLower().AsUInt32(), sum2.GetUpper().AsUInt32()); + return (int)AdvSimd.Extract(sum3, 0); + } + /// /// Reduces even elements of the vector into one sum. /// diff --git a/src/ImageSharp/Formats/Webp/Lossy/LossyUtils.cs b/src/ImageSharp/Formats/Webp/Lossy/LossyUtils.cs index f465741367..e594ed9a8c 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/LossyUtils.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/LossyUtils.cs @@ -226,7 +226,7 @@ internal static class LossyUtils sum = AccumulateSSE16Neon(a.Slice(y * WebpConstants.Bps), b.Slice(y * WebpConstants.Bps), sum); } - return ReduceSum(sum); + return Numerics.ReduceSumArm(sum); } [MethodImpl(InliningOptions.ShortMethod)] @@ -238,7 +238,7 @@ internal static class LossyUtils sum = AccumulateSSE16Neon(a.Slice(y * WebpConstants.Bps), b.Slice(y * WebpConstants.Bps), sum); } - return ReduceSum(sum); + return Numerics.ReduceSumArm(sum); } [MethodImpl(InliningOptions.ShortMethod)] @@ -255,7 +255,8 @@ internal static class LossyUtils // pair-wise adds and widen. Vector128 sum1 = AdvSimd.AddPairwiseWidening(prod1); Vector128 sum2 = AdvSimd.AddPairwiseWidening(prod2); - return ReduceSum(AdvSimd.Add(sum1, sum2)); + + return Numerics.ReduceSumArm(AdvSimd.Add(sum1, sum2)); } // Load all 4x4 pixels into a single Vector128 @@ -273,14 +274,6 @@ internal static class LossyUtils } } - [MethodImpl(InliningOptions.ShortMethod)] - private static int ReduceSum(Vector128 sum) - { - Vector128 sum2 = AdvSimd.AddPairwiseWidening(sum); - Vector64 sum3 = AdvSimd.Add(sum2.GetLower().AsUInt32(), sum2.GetUpper().AsUInt32()); - return (int)AdvSimd.Extract(sum3, 0); - } - [MethodImpl(InliningOptions.ShortMethod)] private static Vector128 AccumulateSSE16Neon(Span a, Span b, Vector128 sum) {