基于围绕this问题答案的讨论,我发现了Java Hotspot优化器的一个非常奇怪的行为。观察到的行为至少可以在Oracle VM 1.7.0_17中看到,但似乎也出现在较旧的Java 6版本中。
首先,我已经意识到优化器显然意识到标准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)<1时才启用优化。 ASIN(1 / SQRT(2))。有没有充分的理由,我没有看到,或者是对优化条件的不必要的限制?
编辑:优化似乎在hotspot / src / share / vm / opto / subnode.cpp中实现
答案 0 :(得分:2)
我认为你的问题是专门针对Oracle JVM的,因为Math的实现依赖于实现。以下是关于Dalvik实施的好答案: native code for Java Math class
一般
所以我们不需要x&lt;的sin / cos函数实现。 0或x> π/ 4。
我想这就是答案(http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5005861):
我们知道almabench结果和osnews文章 三角性能。但是,HotSpot的实现 多年来x86上的sin / cos已经使用并继续使用fsin / fcos x87 这些说明符合质量的范围内的说明 实施要求,基本上是[-pi / 4,pi / 4]。除此之外 范围,fsin / fcos的结果可以是[-1,1]范围内的任何位置 与论证的真正正弦/余弦没什么关系。对于 例如,fsin(Math.PI)只获得结果的大约一半数字 正确。原因是fsin / fcos指令 实现对参数使用不太理想的算法 还原;参数减少过程在bug中解释 4857011。
结论:您已经看到了参数减少算法的结果,而不是优化的限制。