在Swift iOS中交叉产品

时间:2016-06-30 15:44:24

标签: ios arrays xcode swift optimization

我试图在两个向量R ^ n之间做一个交叉乘积,有没有办法以最优化的方式做到这一点?

我查看了加速库但仍无法找到任何内容

2 个答案:

答案 0 :(得分:1)

  

当且仅当n = 0,1,3或7

时,叉积可存在于Rn中

来源:http://www.math.csusb.edu/faculty/pmclough/CP.pdf

所以不,你肯定找不到任何能做到这一点的图书馆。如果你的意思是元素,你可以使用Accelerate。这是一个简短的测试:

import Accelerate

let n = 10_000_000

let a = (0..<n).map{ _ in Double(arc4random()) / Double(UInt32.max) }
let b = (0..<n).map{ _ in Double(arc4random()) / Double(UInt32.max) }

print("A: [\(a.prefix(10).map{ "\($0)" }.joinWithSeparator(", ")), ...]")
print("B: [\(b.prefix(10).map{ "\($0)" }.joinWithSeparator(", ")), ...]")

var result = [Double](count: n, repeatedValue: 0)

let start = mach_absolute_time()
vDSP_vmulD(a, 1, b, 1, &result, 1, UInt(n))
let stop = mach_absolute_time()

let time = Double(stop - start) / Double(NSEC_PER_SEC)

print("Time: \(time) for \(n) elements")
print("Result: [\(result.prefix(10).map{ "\($0)" }.joinWithSeparator(", ")), ...]")

输出:

A: [0.269752697849123, 0.851672558312228, 0.0668649589798564, 0.0955562389212559, 0.255900985620893, 0.93693982901446, 0.085282990495973, 0.732230591525377, 0.588338787804437, 0.952581417968632, ...]
B: [0.750105029379508, 0.0454008649209051, 0.863010750120275, 0.308104009904923, 0.700024090637459, 0.327355608653127, 0.679469040520366, 0.666848364208557, 0.0567599588671606, 0.623293806245386, ...]
Time: 0.024393279 for 10000000 elements
Result: [0.202342855345318, 0.0386666707767751, 0.0577051784059674, 0.0294412603830718, 0.179136854752495, 0.306712507998386, 0.0579471517250063, 0.488286772182162, 0.0333940853957349, 0.593738097764296, ...]
对于1000万个元素,

0.024秒非常快

答案 1 :(得分:1)

并行执行

如果您正在寻找Elementwise产品操作

  

a =(1.0,2.0)

     

b =(3.0,4.0)

     

a * b =(a1 * b1,a2 * b2)=(3.0,8.0)

并且您希望在iOS上可以获得禁用的可能性能,您应该使用simd框架(单指令多数据)。

import simd

let v0 = float2(1.0, 2.0)
let v1 = float2(3.0, 4.0)

let res = v0 * v1
print(res) // float2(3.0, 8.0)

为什么simd这么快?

如果没有simd,计算a*b将需要执行2个步骤

  1. 计算a1 * b1并将结果放入res1
  2. 计算a2 * b2并将结果放入res2
  3. 另一方面,使用simd两个操作并行完成。这是可能的,因为2个步骤具有相同的操作不同的数据。这正是simd允许你做的事情。

    更多

    来自Wikipedia

      

    单指令,多数据(SIMD),是Flynn分类中的一类并行计算机。它描述了具有多个处理元素的计算机,这些处理元素同时对多个数据点执行相同的操作。

         

    因此,这样的机器利用数据级并行性,而不是并发性:同时(并行)计算,但在给定时刻只有一个进程(指令)。

         

    SIMD特别适用于调整数字图像中的对比度或调整数字音量等常见任务。

         

    大多数现代CPU设计都包含SIMD指令,以提高多媒体使用的性能。