|  | 
| 5 | 5 | using System.Runtime.CompilerServices; | 
| 6 | 6 | using System.Runtime.InteropServices; | 
| 7 | 7 | using System.Runtime.Intrinsics; | 
|  | 8 | +using System.Runtime.Intrinsics.Arm; | 
| 8 | 9 | using System.Runtime.Intrinsics.X86; | 
| 9 | 10 | using SixLabors.ImageSharp.Memory; | 
| 10 | 11 | 
 | 
| @@ -122,12 +123,26 @@ static void SumVertical(Span<float> target, Span<float> source) | 
| 122 | 123 |                 ref Vector256<float> sourceVectorRef = ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(source)); | 
| 123 | 124 | 
 | 
| 124 | 125 |                 // 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"); | 
| 125 | 127 |                 nuint count = source.Vector256Count<float>(); | 
| 126 | 128 |                 for (nuint i = 0; i < count; i++) | 
| 127 | 129 |                 { | 
| 128 | 130 |                     Unsafe.Add(ref targetVectorRef, i) = Avx.Add(Unsafe.Add(ref targetVectorRef, i), Unsafe.Add(ref sourceVectorRef, i)); | 
| 129 | 131 |                 } | 
| 130 | 132 |             } | 
|  | 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 | +            } | 
| 131 | 146 |             else | 
| 132 | 147 |             { | 
| 133 | 148 |                 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) | 
| 200 | 215 |                 ref Vector256<float> targetVectorRef = ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(target)); | 
| 201 | 216 | 
 | 
| 202 | 217 |                 // 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"); | 
| 203 | 219 |                 nuint count = target.Vector256Count<float>(); | 
| 204 |  | -                var multiplierVector = Vector256.Create(multiplier); | 
|  | 220 | +                Vector256<float> multiplierVector = Vector256.Create(multiplier); | 
| 205 | 221 |                 for (nuint i = 0; i < count; i++) | 
| 206 | 222 |                 { | 
| 207 | 223 |                     Unsafe.Add(ref targetVectorRef, i) = Avx.Multiply(Unsafe.Add(ref targetVectorRef, i), multiplierVector); | 
| 208 | 224 |                 } | 
| 209 | 225 |             } | 
|  | 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 | +            } | 
| 210 | 239 |             else | 
| 211 | 240 |             { | 
| 212 | 241 |                 ref Vector<float> targetVectorRef = ref Unsafe.As<float, Vector<float>>(ref MemoryMarshal.GetReference(target)); | 
|  | 
0 commit comments