Swift SIMD or Accelerate Sum UInt32

622 views Asked by At

Is there a built-in facility to Accelerate or elsewhere for summing an array of UInt32 using accelerated vector operations?

1

There are 1 answers

2
Daniel Lemire On BEST ANSWER

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