2013-03-12 8 views
13

this質問に対する回答を中心に議論したところ、Javaホットスポットオプティマイザの実際の動作は非常に奇妙です。観察された動作は、少なくとも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)は各反復で評価されませんが、ループ内でxが変更されない限り、メソッドMath.sinには関連する副作用がなく、結果は不変であることがオプティマイザによって認識されます。

ここで、xを0.5から1.0に変更するだけで、この最適化が無効になることがわかりました。さらなるテストでは、abs(x)< asin(1/sqrt(2))の場合にのみ最適化が有効になることが示されています。私には分かりませんが、それは最適な条件の不必要な制限ですか?

編集:最適化は、数学の実装は実装依存であるので、私は、特にOracle JVMに関するご質問を考えてホットスポット/ srcに/共有/ VM /光/ subnode.cpp

+6

「式Math.sin(x)は各反復で評価されません」ということをどのように知っていますか?あなたはアセンブリコードを見ましたか?または測定時間?また、 'Math.sin'はJava 1.7の組み込みメソッドであることに注意してください。コード実行はJDKソースに表示されるJavaコードではありません。 – assylias

+0

@assylias:時間を測定することによって、しかし良い点があります。私は引数 jarnbjo

+0

@jarbjo x86_64 cpusの実装は、次のとおりです。http://hg.openjdk.java.net/jdk7u/jdk7u/hotspot/file/6e9aa487055f/src/cpu/x86/vm/stubGenerator_x86_64.cpp(2878行目) – assylias

答えて

2

に実装しているようです。 native code for Java Math class

一般

  1. 罪(A)*罪(A)+ COS(A)* COS(A)= 1
  2. 罪(PI:ここでのDalvik例の実装についての良い答えがあります/ 2 - A)= COS(A)
  3. 罪(-a)= -sin(a)の
  4. COS(-a)= COS(A)

ので、私たちは罪を必要としません/ cos関数の実装x < 0またはx> pi/4についての言及。

私はこれが答え(http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5005861)であると仮定します

我々はalmabench結果として 三角パフォーマンスにosnewsの記事を認識しています。しかし、 sin/cos(x86版)は、基本的に[-pi/4、pi/4]という実装要件の品質を満足する範囲でfsin/fcos x87 命令を使用しています。 ]。その の範囲外では、fsin/fcosの結果は、[-1、1] の範囲内のどこでも、引数の正弦/余弦とはほとんど関係ありません。 の例では、fsin(Math.PI)は結果の数字の約半分しか得られません 。これは、fsin/fcos命令 の実装では、引数には理想的ではないアルゴリズムを使用しています。 reduce;引数還元プロセスはバグで 4857011.

結論を説明している:あなたは、最適化の、限定ではなく行動で、引数縮小アルゴリズムの結果を見てきました。

+0

To 'Math.Sin(Math.Pi)'が正確に「特徴」をゼロにしないという事実はどれくらいの程度ですか?私は、 'Math.Sin'を呼び出す実際のコードのほうが、1/4LSBから1/2LSBの丸め誤差を持つ引数を使っていると仮定します。 'Math.Pi'を使った引数の削減は、ほとんどの現実世界のアプリケーションでこの丸め誤差を打ち消しますが、πを使った引数の削減はそれを保存します。 – supercat