iPhone(Swift,不是 ObjectC)上的最快平方根反比
Fastest Inverse Square Root on iPhone (Swift, not ObjectC)
参考
Fastest Inverse Square Root on iPhone
我需要在 iPhone iOS Swift 上做一个 "Fastest Inverse Square Root",这应该比 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
}
唯一棘手的部分是如何在浮动之间进行强制转换
点数和整数类型,最简单的方法是使用
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
}
参考 Fastest Inverse Square Root on iPhone
我需要在 iPhone iOS Swift 上做一个 "Fastest Inverse Square Root",这应该比 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
}
唯一棘手的部分是如何在浮动之间进行强制转换
点数和整数类型,最简单的方法是使用
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)
.
最大相对误差低于 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
}