【问题标题】:Strange behaviour of the Hotspot loop condition optimizer热点循环条件优化器的奇怪行为
【发布时间】:2023-03-14 02:52:01
【问题描述】:

基于对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)

编辑:优化似乎在hotspot/src/share/vm/opto/subnode.cpp中实现

【问题讨论】:

  • 你怎么知道“表达式 Math.sin(x) 不会为每次迭代计算”?你看过汇编代码吗?还是测量时间?另请注意,Math.sin 是 Java 1.7(可能之前)中的内部方法,因此运行的代码不是 JDK 源代码中显示的 Java 代码...
  • @assylias:通过测量时间,但你有一个很好的观点。我想知道它是否是 Math.sin 的实际实现,它针对 arguments
  • @jarbjo x86_64 cpus 的实现在这里:hg.openjdk.java.net/jdk7u/jdk7u/hotspot/file/6e9aa487055f/src/… 在第 2878 行附近。

标签: java jvm-hotspot optimization


【解决方案1】:

我认为您的问题是关于 Oracle JVM,因为 Math 的实现是依赖于实现的。这是关于 Dalvik 实现的好答案,例如: native code for Java Math class

一般

  1. sin(a) * sin(a) + cos(a) * cos(a) = 1
  2. sin(pi/2 - a) = cos(a)
  3. sin(-a) = -sin(a)
  4. cos(-a) = cos(a)

所以我们不需要 x pi/4 的 sin/cos 函数实现。

我想这就是答案 (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 指令 实现对 参数使用不太理想的算法 减少;参数减少过程在错误中解释 4857011.

结论:您已经看到了参数缩减算法的实际效果,而不是优化的限制。

【讨论】:

  • Math.Sin(Math.Pi) 的“特征”在多大程度上不能精确地产生零?我假设大多数调用Math.Sin 的实际代码都使用具有大约 1/4LSB 到 1/2LSB 舍入误差的参数。在大多数实际应用中,使用Math.Pi 减少参数会抵消这种舍入误差,而使用 π 减少参数会保留它。
猜你喜欢
  • 2021-02-17
  • 1970-01-01
  • 2021-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-04
  • 2014-12-05
  • 1970-01-01
相关资源
最近更新 更多