Reputation: 1498
Is there a built-in facility to Accelerate or elsewhere for summing an array of UInt32 using accelerated vector operations?
Upvotes: 1
Views: 655
Reputation: 3618
I suppose that you want to accelerate a function such as
func scalarsum (_ test_array: [UInt32]) -> UInt32 {
var result : UInt32 = 0
for x in test_array {
result = result &+ x
}
return result
}
So maybe you can write something complicated such as this...
func simdsum (_ test_array: [UInt32]) -> UInt32 {
var tmpvector=uint4(0)
// assume test_array.count is divisible by four
let limit = test_array.count/4
for i in 0..<limit {
let thisvector = uint4(test_array[4*i],test_array[4*i+1],test_array[4*i+2],test_array[4*i+3])
tmpvector = tmpvector &+ thisvector
}
return tmpvector[0] + tmpvector[1] + tmpvector[2] + tmpvector[3]
}
However, let us look what assembly swift produces for the first function...
simdsum[0x100001070] <+448>: movdqu 0x20(%rcx,%rdi,4), %xmm2
simdsum[0x100001076] <+454>: movdqu 0x30(%rcx,%rdi,4), %xmm3
(...)
simdsum[0x10000107c] <+460>: paddd %xmm2, %xmm0
simdsum[0x100001080] <+464>: paddd %xmm3, %xmm1
Ah! Ah! Swift is smart enough to vectorize the sum.
So the short answer is that if you are trying to manually design a sum function using SIMD instructions in Swift, you are probably wasting your time... the compiler will do the work for you automagically.
See further code at https://github.com/lemire/Code-used-on-Daniel-Lemire-s-blog/tree/master/extra/swift/simdsum
Upvotes: 4