基于对this问题答案的讨论,我发现了Java Hotspot优化器的一个非常奇怪的行为。观察到的行为至少可以在Oracle 1.7.0_17中看到,但似乎也出现在较早的Java6版本中。
首先,我已经意识到优化器显然意识到标准API中的一些方法是不变的,并且没有副作用。在执行像double x=0.5; for(double d = 0; d < Math.sin(x); d += 0.001);这样的循环时,不会为每次迭代计算表达式Math.sin(x),但是优化器知道Math.sin方法没有相关的副作用,并且只要x没有在循环中修改,结果就是不变的。
现在我注意到,简单地将x从0.5更改为1.0会禁用此优化。进一步的测试表明,只有当abs(x) < asin(1/sqrt(2))时,才会启用优化。这是不是有一个很好的理由,我看不出来,或者这是对优化条件的不必要的限制?
编辑:优化似乎是在hotspot/src/share/vm/opto/subnode.cpp中实现的
发布于 2013-06-18 05:46:21
我认为你的问题是关于Oracle JVM的,因为Math的实现依赖于实现。下面是关于Dalvik实现的很好的答案,例如:native code for Java Math class
一般而言
因此,对于x<0或x> pi/4,我们不需要sin/cos函数实现。
我想这就是答案(http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5005861):
我们知道关于三角性能的almabench结果和osnews文章。但是,多年来在x86上实现sin/cos的HotSpot一直使用并继续使用fsin/fcos x87指令,这些指令满足实现质量要求,基本上是- pi/4,pi/4。在该范围之外,fsin/fcos的结果可以在-1,1范围内的任何位置,与参数的真正弦/余弦几乎没有关系。例如,fsin(Math.PI)只能得到大约一半的正确结果。这是因为fsin/fcos指令实现使用了不太理想的参数减少算法;参数减少过程在错误4857011中进行了解释。
结论:您已经看到了参数缩减算法的实际效果,而不是优化的局限性。
https://stackoverflow.com/questions/15363809
复制相似问题