men*_*gen 3 macos loops simd accelerate-framework swift
我正在使用C和Swift 3.0代码,使用来自Apple的vecLib和Accelerate框架作为基于C lang的项目和Swift playground中的动态库+我的代码.
并与呼叫从苹果公司的包装情况框架 SIMD指令的与像1或<4个元素计算功能vvcospif()从框架是比简单的非标准慢cos(x * PI)时功能从循环调用邻近1.000倍的例子.
我知道vvcospif()和之间的区别cos(),我应该完全vvcospif()使用x * PI.
在游乐场中的示例,您只需复制代码并运行它:
import Cocoa
import Accelerate
func cosine_interpolate(alpha: Float, a: Float, b: Float) -> Float {
let ft: Float = alpha * 3.1415927;
let f: Float = (1 - cos(ft)) * 0.5;
return a + f*(b - a);
}
var start: Date = NSDate() as Date
var interp: Float;
for index in 0..<1000 {
interp = cosine_interpolate(alpha: 0.25, a: 1.0, b: 0.75)
}
var end = NSDate();
var timeInterval: Double = end.timeIntervalSince(start);
print("cosine_interpolate in \(timeInterval) seconds")
func fast_cosine_interpolate(alpha: Float, a: Float, b: Float) -> Float {
var x: Float = alpha
var count: Int32 = 1
var result: Float = 0
vvcospif(&result, &x, &count)
let SINSIN_HALF_X: Float = (1 - result) * 0.5;
return a + SINSIN_HALF_X * (b - a);
}
start = NSDate() as Date
for index in 0..<1000 {
interp = fast_cosine_interpolate(alpha: 0.25, a: 1.0, b: 0.75)
}
end = NSDate();
timeInterval = end.timeIntervalSince(start);
print("fast_cosine_interpolate in \(timeInterval) seconds")
Run Code Online (Sandbox Code Playgroud)
我的问题是:
vvcospif()这个例子很慢?可能是因为vvcospif()它是Objective-C运行时下的包装器,并且转换数据结构/从Intel SIMD复制内存 - > Objective-C - > Swift运行时比较小cos()吗?
#include <Accelerate/Accelerate.h>
vvcospif(resultVector, inputVector, &count);
Run Code Online (Sandbox Code Playgroud)
when inputVector和resultVector是带有1或2个元素的小数组或只是float变量,并且循环调用~1.000.000次.
cos(x * PI) 计算时间接近20毫秒.
和
vvcospif(x)处理一个float或float array[2]- 计算时间接近80毫秒!加速在哪里?:)
是的,在Xcode中我使用-O -whole-module-optimization整个模块选择的编译器优化.启用.
有关示例的更详细讨论,请参阅"Fast Bezier简介(以及尝试Accelerate.framework)".
第一个基本问题是非内联函数调用非常昂贵.如果您可以在性能关键代码中提供帮助,则不需要函数调用.在模块中,编译器通常可以为您内联函数,并且可以为您内联部分stdlib.但是当你开始跨越模块障碍时,Swift通常无法优化呼叫.
SIMD功能的关键在于您以正确的格式设置所有数据,然后只调用一次.这样,函数调用的成本由您调用的SIMD优化代码组成.
但请记住,您不必调用Accelerate来获得SIMD优化.编译器完全能够注意到你已经编写了一个循环并将其转换为内联SIMD算法本身(并且它一直这样做).因此,对于许多简单的问题,编译器无论如何都会赢.想一想:如果vvcospif以1计数的呼叫比呼叫更快cos,那么他们不会cos这样实现吗?
我没有太多地使用你的代码,但是如果你想用Accelerate改进它的性能,你想要考虑如何安排你所有的输入数据,这样你就可以vvcospif用大N 调用一次.在这种情况下很可能它会比循环快得多(因为cos它不是微不足道的).
如果您想在实践中获得Accelerate的示例,以及如何组织数据,请参阅PinchText.这段代码是基于最多10次实时动画,通过动画计算满载几千个字形的页面的偏移量(请参阅PinchText.mov了解结果如何).特别要看一下adjustViewPositions:count:forTouchPoint:.注意如何count变大,并且数据在没有循环的情况下逐步变换.即使将(非常昂贵的)ObjC方法调用抛入该方法也无关紧要,因为它只进行了一次.摆脱循环中的函数调用是性能编程的重要组成部分.