Skip to content

Commit e646c4b

Browse files
Merge pull request #2429 from stefannikolei/stefannikolei/arm/componentconverter
Add AdvSimd in ComponentProcessor
2 parents 10f5e8f + 8a68c67 commit e646c4b

File tree

1 file changed

+30
-1
lines changed

1 file changed

+30
-1
lines changed

src/ImageSharp/Formats/Jpeg/Components/Encoder/ComponentProcessor.cs

+30-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Runtime.CompilerServices;
66
using System.Runtime.InteropServices;
77
using System.Runtime.Intrinsics;
8+
using System.Runtime.Intrinsics.Arm;
89
using System.Runtime.Intrinsics.X86;
910
using SixLabors.ImageSharp.Memory;
1011

@@ -122,12 +123,26 @@ static void SumVertical(Span<float> target, Span<float> source)
122123
ref Vector256<float> sourceVectorRef = ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(source));
123124

124125
// Spans are guaranteed to be multiple of 8 so no extra 'remainder' steps are needed
126+
DebugGuard.IsTrue(source.Length % 8 == 0, "source must be multiple of 8");
125127
nuint count = source.Vector256Count<float>();
126128
for (nuint i = 0; i < count; i++)
127129
{
128130
Unsafe.Add(ref targetVectorRef, i) = Avx.Add(Unsafe.Add(ref targetVectorRef, i), Unsafe.Add(ref sourceVectorRef, i));
129131
}
130132
}
133+
else if (AdvSimd.IsSupported)
134+
{
135+
ref Vector128<float> targetVectorRef = ref Unsafe.As<float, Vector128<float>>(ref MemoryMarshal.GetReference(target));
136+
ref Vector128<float> sourceVectorRef = ref Unsafe.As<float, Vector128<float>>(ref MemoryMarshal.GetReference(source));
137+
138+
// Spans are guaranteed to be multiple of 8 so no extra 'remainder' steps are needed
139+
DebugGuard.IsTrue(source.Length % 8 == 0, "source must be multiple of 8");
140+
nuint count = source.Vector128Count<float>();
141+
for (nuint i = 0; i < count; i++)
142+
{
143+
Unsafe.Add(ref targetVectorRef, i) = AdvSimd.Add(Unsafe.Add(ref targetVectorRef, i), Unsafe.Add(ref sourceVectorRef, i));
144+
}
145+
}
131146
else
132147
{
133148
ref Vector<float> targetVectorRef = ref Unsafe.As<float, Vector<float>>(ref MemoryMarshal.GetReference(target));
@@ -200,13 +215,27 @@ static void MultiplyToAverage(Span<float> target, float multiplier)
200215
ref Vector256<float> targetVectorRef = ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(target));
201216

202217
// Spans are guaranteed to be multiple of 8 so no extra 'remainder' steps are needed
218+
DebugGuard.IsTrue(target.Length % 8 == 0, "target must be multiple of 8");
203219
nuint count = target.Vector256Count<float>();
204-
var multiplierVector = Vector256.Create(multiplier);
220+
Vector256<float> multiplierVector = Vector256.Create(multiplier);
205221
for (nuint i = 0; i < count; i++)
206222
{
207223
Unsafe.Add(ref targetVectorRef, i) = Avx.Multiply(Unsafe.Add(ref targetVectorRef, i), multiplierVector);
208224
}
209225
}
226+
else if (AdvSimd.IsSupported)
227+
{
228+
ref Vector128<float> targetVectorRef = ref Unsafe.As<float, Vector128<float>>(ref MemoryMarshal.GetReference(target));
229+
230+
// Spans are guaranteed to be multiple of 8 so no extra 'remainder' steps are needed
231+
DebugGuard.IsTrue(target.Length % 8 == 0, "target must be multiple of 8");
232+
nuint count = target.Vector128Count<float>();
233+
Vector128<float> multiplierVector = Vector128.Create(multiplier);
234+
for (nuint i = 0; i < count; i++)
235+
{
236+
Unsafe.Add(ref targetVectorRef, i) = AdvSimd.Multiply(Unsafe.Add(ref targetVectorRef, i), multiplierVector);
237+
}
238+
}
210239
else
211240
{
212241
ref Vector<float> targetVectorRef = ref Unsafe.As<float, Vector<float>>(ref MemoryMarshal.GetReference(target));

0 commit comments

Comments
 (0)