代码之家  ›  专栏  ›  技术社区  ›  Hugues M.

使用Math.fma的准确性和性能优势是什么?

  •  23
  • Hugues M.  · 技术社区  · 8 年前

    我今天才注意到 Math.fma(a, b, c) 在Java 9中 a*b + c
    (用于 double float 数值)。

    返回三个参数的融合乘法和;也就是说,返回前两个参数与第三个参数求和的精确乘积,然后四舍五入到最近的浮点值。使用舍入到最近的偶数舍入模式进行舍入。相反,如果a*b+c作为正则浮点表达式计算,则会涉及两个舍入误差,第一个用于乘法运算,第二个用于加法运算。

    看起来是这样的 ,由2取整改为1。对吗?这是以CPU能力为条件的,还是我们可以依靠它 总是

    性能优势 也我有兴趣了解当前平台/CPU的实际好处,也有兴趣了解假设的未来好处。

    编辑(尽量让它不那么宽泛):我不是在寻找非常详细的答案:是/否的几个项目,以纠正/确认我的理解,加上几个指针,将足以让我标记一个答案为接受。我对准确性和;性能方面, 我认为他们是一起的。。。

    2 回复  |  直到 8 年前
        1
  •  16
  •   geza    8 年前

    是的,正是因为你所说的原因,FMA提高了准确性。

    如果CPU FMA不可用,Java将使用 慢解决方案:它使用 java.math.BigDecimal (这是当前的解决方案-它可能会在未来发生变化,但我敢打赌,与CPU FMA相比,它总是很慢)。

        2
  •  9
  •   Eugene    8 年前

    sysctl -n machdep.cpu.brand_string
    

    我可以看到我的cpu是 Intel(R) Core(TM) i7-5557U CPU @ 3.10GHz FMA ,您可以通过以下方式看到:

    sysctl -a | grep machdep.cpu | grep FMA
    

    这些方法(一个用于 double float )注释为 @HotSpotIntrinsicCandidate 这意味着 JIT 可以用实际的CPU本机指令替换它们-如果可以的话,但这意味着该方法必须 -多次调用,这是一个依赖于JVM的事情。

     public static void main(String[] args) {
    
        double result = 0;
        for (int i = 0; i < 50_000; ++i) {
            result = result + mine(i);
        }
        System.out.println(result);
    }
    
    private static float mine(int x) {
        return Math.fma(x, x, x);
    }
    

     java -XX:+UnlockDiagnosticVMOptions  
          -XX:+PrintInlining 
          -XX:+PrintIntrinsics 
          -XX:CICompilerCount=2 
          -XX:+PrintCompilation  
          org.so/FMATest
    

    那里会有一堆线,但其中之一是:

     @ 6   java.lang.Math::fma (12 bytes)   (intrinsic)
    

    这意味着JVM确实为FMA指令使用了一种内在方法。