Java:Math.sqrt()的32位fp实现

时间:2015-06-11 08:53:22

标签: java performance math 32-bit

标准的Math.sqrt()方法在Java中看起来相当快,但它有一个固有的缺点,它始终涉及64位操作,除了在处理32位{{1值。是否可以使用float作为参数的自定义方法做得更好,仅执行32位操作,并返回float作为结果?

我看到了:

Fast sqrt in Java at the expense of accuracy

它只是强化了Math.sqrt()通常难以击败的概念。我也看到了:

http://www.codeproject.com/Articles/69941/Best-Square-Root-Method-Algorithm-Function-Precisi

它向我展示了一堆有趣的C ++ / ASM黑客,我根本无法直接移植到Java。虽然sqrt14作为JNI调用的一部分可能很有趣。 。

我也查看了Apache Commons FastMath,但看起来该库默认为标准的Math.sqrt(),所以没有帮助。然后是Yeppp!:

http://www.yeppp.info/

但我还没有打扰过它。

2 个答案:

答案 0 :(得分:6)

对于32位值,您无需加速sqrt。 HotSpot JVM会自动为您完成。

JIT编译器非常智能,能够识别f2d -> Math.sqrt() -> d2f模式,并用更快的sqrtss CPU指令代替sqrtsd替换它。 The source

基准:

@State(Scope.Benchmark)
public class Sqrt {
    double d = Math.random();
    float f = (float) d;

    @Benchmark
    public double sqrtD() {
        return Math.sqrt(d);
    }

    @Benchmark
    public float sqrtF() {
        return (float) Math.sqrt(f);
    }
}

结果:

Benchmark    Mode  Cnt       Score      Error   Units
Sqrt.sqrtD  thrpt    5  145501,072 ± 2211,666  ops/ms
Sqrt.sqrtF  thrpt    5  223657,110 ± 2268,735  ops/ms

答案 1 :(得分:0)

你似乎知道JNI:

只需为C&C的标准库double sqrt(double)中的float sqrt(float)math.h编写一个最小包装器,然后比较性能。

提示:除非你做了很多平方根,否则你不会觉得有什么不同,然后使用SIMD指令一次做多个sqrts的性能优势很可能会主导效果。您需要从Java获取一个与内存对齐的浮点值数组,如果您使用的是Java标准库,这可能会非常困难。