I have written a SIMD interpolator like this:
public struct Fade_SIMD8 {
public init() {}
public func interpolate(_ t: SIMD8<Float>, between a: SIMD8<Float>, and b: SIMD8<Float>) -> SIMD8<Float> {
a + ((3 - 2 * t) * t * t) * (b - a)
}
}
And also the SIMD32 version:
public struct Fade_SIMD32 {
public init() {}
public func interpolate(_ t: SIMD32<Float>, between a: SIMD32<Float>, and b: SIMD32<Float>) -> SIMD32<Float> {
a + ((3 - 2 * t) * t * t) * (b - a)
}
}
and then, I thought that I should rather write a SIMD generic version, so that I don't have to write N times the same thing:
public struct Fade_SIMD<S: SIMD> where S.Scalar == Float {
public init() {}
public func interpolate(_ t: S, between a: S, and b: S) -> S {
a + ((3 - 2 * t) * t * t) * (b - a)
}
}
But while measuring the performance using XCTest, I found out that:
a) The SIMD8 and SIMD32 version are much slower than a non-SIMD counterpart. This seem to also be documented here: Swift SIMD operands slower than a simple while loop
b) The generic version is 100 times slower than the non-generic version.
So the questions are:
- Is this slowing down of generics a known thing ?
- Is it really true that the Swift compiler optimises standard code by using SIMD when needed (so that, in some way, we don't have to care about SIMDing our code) ?