iPhone上最快的反方形根(Swift,而不是ObjectC)

时间:2015-11-11 03:39:29

标签: swift sqrt

参考 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
}

1 个答案:

答案 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
}