当对向量法和正态法都进行基准测试时,存在时间上的差异。
正态方法
let arrayA: [Float] = [1,2,3]
let arrayB: [Float] = [10,20,30]
let arrayResult:[Float] = zip(arrayA,arrayB).map() {$0 + $1}
Time required: 0.0025310516357421875使用加速
let p = double3(1, 2, 3)
let q = double3(10, 20, 30)
print(p + q)
Time required: 0.0009039640426635742它是如何在内部工作的。在新的方法中,它变得快了2.79倍。
发布于 2019-12-11 19:52:23
SIMD代表“单指令,多数据”。这意味着某些指令可以同时对多组数据进行操作。不同类型的硬件支持不同的SIMD指令。在您的示例中,您能够同时执行三个浮点加法操作。
发布于 2019-12-11 22:24:00
首先,这些是非常不同的操作,所以在微基准中比较它们并不是特别有用。您的第一个示例可以添加在运行时确定的任意数量的值。第二个示例恰好添加了3对。这意味着第一个必须为存储分配内存,这可能是非常昂贵的。
此外,请确保仔细分析,并打开优化。第一个例子非常容易被优化。第二个不是,像这样的非常小的操作的时间是非常困难的。测量的行为可能会使你的数字发生很大的偏差。(也就是说,我对这些数字并不感到特别惊讶。)
但正确的比较应该是这样:
let p = (1.0, 2.0, 3.0)
let q = (10.0, 20.0, 3.0)
let result = (p.0 + q.0, p.1 + q.1, p.2 + q.2)这与double3代码做了同样的事情,我希望它的速度大致一样快。它可能会更快或更慢,但它应该很接近,因为优化器很可能能够将其转换为非常类似于simd代码的内容。
有关SIMD代码真正在做什么的更多信息,请参阅Rob的答案,但关键功能是它是一个硬件级别的功能,可以将相同的操作同时应用于多个值。不是多线程意义上的并发,而是由硬件同时进行的。但要使用此功能,输入和输出必须采用非常精确的格式和布局。(实际上,您正在使用的double3实际上在内部转换为double4,因为操作一次在2或4个Double上完成;最后一个被忽略。)
发布于 2019-12-11 19:49:03
来自Accelerate documentation
Accelerate通过利用其向量处理能力,在CPU上提供高性能、高能效的计算。下面的加速库对该功能进行抽象,以便为它们编写的代码在运行时为可用的处理器执行适当的指令。
https://stackoverflow.com/questions/59284364
复制相似问题