参考 Fastest Inverse Square Root on iPhone
我需要做一个"最快的反平方根"在iPhone iOS Swift上,它应该比1/sqrt(float)
更快。
我该怎么做?
在嵌入式C编程中,它是:
// Fast inverse square-root
// See: http://en.wikipedia.org/wiki/Fast_inverse_square_root
func invSqrt(x: Float) -> Float {
var halfx : Float = 0.5 * x
var y : Float = x
long i = *(long*)&y
i = 0x5f3759df - (i>>1)
y = *(float*)&i
y = y * (1.5 - (halfx * y * y))
return y
}
答案 0 :(得分:5)
唯一棘手的部分是如何在浮动之间进行强制转换
点数和整数类型,最简单的方法是使用
memcpy()
:
// Fast inverse square-root
// See: http://en.wikipedia.org/wiki/Fast_inverse_square_root
func invSqrt(x: Float) -> Float {
let halfx = 0.5 * x
var y = x
var i : Int32 = 0
memcpy(&i, &y, 4)
i = 0x5f3759df - (i >> 1)
memcpy(&y, &i, 4)
y = y * (1.5 - (halfx * y * y))
return y
}
我在随机播放1.000.000的iPhone 6s上进行了一些性能测试
结果是0到1000范围内的浮点数
invSqrt(x)
比1.0/sqrt(x)
快约40%。
最大相对误差低于0.176%,证实了界限 维基百科的文章。
我还从vvrsqrtf
进行了测试
加速框架,但这实际上慢
至少在使用单一浮动调用时调用1.0/sqrt(x)
点数。
从 Swift 3开始, memcpy()
可以替换为bitPattern:
Float
的方法以及UInt32
中的相应构造函数:
func invSqrt(x: Float) -> Float {
let halfx = 0.5 * x
var i = x.bitPattern
i = 0x5f3759df - (i >> 1)
var y = Float(bitPattern: i)
y = y * (1.5 - (halfx * y * y))
return y
}