問題タブ [jmh]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
java - この forkjoinreuse と forkjoindeeprecursive はどういう意味ですか?
私はこのマイクロベンチマークを理解しようとしています。
ソースには、 と の 4 種類の ForkJoin がForkJoinreuse
ありForkJoinrecursivedeep
ます。ソースを読んでも、ForkJoin
と との違いがわかりません。ForkJoinrecursive
java - JMH: パフォーマンス比較
私は自分のプログラムのパフォーマンスを改善しようとしています。JMH を使用して 2 つのバージョンを比較しましたが、実際に違いがあるかどうかはわかりません。
私の結果の例:
これらの結果は、バージョン 1 とバージョン 2 の実際の違いを示していますか?
java - JMH 使用時の奇妙な出力
私は単純なアプリケーションをベンチマークするために jmh を使用しています (SO question Unexpected Scalability results in java fork-joinから) Maven を使用し、 http://openjdk.java.net/projects/code-toolsでアドバイスされているコマンドライン アプローチに従っています/jmh/ . ベンチマークを正常にセットアップして構築した後、avgt モードを使用して次のベンチマーク結果を取得しました。
この出力をどのように解釈すればよいかわかりませんが、何か問題があったことは確かです...? これを何またはどのようにデバッグするか考えていますか?
java - CPU の div 命令と HotSpot の JIT コードの間の大きなパフォーマンス ギャップ
CPU の初期から、整数除算命令が高価であることは一般的な知識でした。何十億ものトランジスタを贅沢に搭載した CPU で、今日がどれほど悪いかを見に行きました。ハードウェアidiv
命令は、命令を含まない JIT コンパイラが発行できるコードよりも、定数除数に対して依然として大幅にパフォーマンスが悪いことがわかりましたidiv
。
これを専用のマイクロベンチマークで明らかにするために、次のように記述しました。
divVar
簡単に言えば、1 つの ( ) が配列から読み取った数値で除算を実行し、もう 1 つはコンパイル時の定数で除算することを除いて、すべての点で同一の 2 つのメソッドがあります。結果は次のとおりです。
パフォーマンスの比率は非常に異常です。私の予想では、最新の Intel プロセッサには十分なスペースがあり、そのエンジニアは、複雑ではあるがパフォーマンスの高い除算アルゴリズムをハードウェアに実装するのに十分な関心を持っています。それでも、JIT コンパイラーは、同じジョブを実行する他の命令のストリームをインテルに送信するという点でインテルに勝っていますが、その速度はわずか 7 倍です。どちらかといえば、専用のマイクロコードは、アセンブリ命令のパブリック API を介して JIT が実行できるものよりも CPU を有効に活用できるはずです。
idiv
なぜまだこんなに遅いのか、根本的な制限は何ですか?
頭に浮かぶ説明の 1 つは、プロセスの非常に遅い段階で初めて被除数を含む除算アルゴリズムが存在するという仮説です。JIT コンパイラは、コンパイル時に除数のみを含む最初の部分を評価し、アルゴリズムの 2 番目の部分のみをランタイム コードとして出力するため、有利なスタートを切ることができます。その仮説は本当ですか?
java-8 - paralell() 使用時の JMH スループット値の不一致
私はJHMを初めて使用します。テストするために、次の簡単な方法を書きました
テストの結果は大きく変わりました
複数回実行した後も同じ動作が観察されました。ウォームアップの反復を減らした後でも、5/6 の反復の後でも ops/s の低下が見られました。並列操作を使用したテスト スイートのその他のベンチマークは、一貫して実行されました。
私は JMH を初めて使用します。いくつか質問があります。
- 分散を少なくするために調整できる JMH の構成パラメーターはありますか?
- これは、問題のメソッドを複数回繰り返したときに予想される動作ですか?
- JHM が正しく報告している場合、このメソッドをデバッグして、ops/s がドロップする理由を見つけるにはどうすればよいですか?
いくつかの仕様
編集
すべてのフィードバックに感謝します。
今朝、ラップトップの電源を一晩中オフにして、ベンチマークを再実行しました。一貫性のない動作は完全になくなりました。反復を 1000 に増やしても、ops/s は一貫したままでした。
CPU 温度を確認すると、84 度で安定していました。
この問題を再現できませんでした。次に CPU が過熱していると思われる場合は、このベンチマークを再実行し、CPU 温度を監視して、この動作が再発するかどうかを確認したいと思います。
実行時に使用すると、 Arrays.stream().map().sum() の不安定なパフォーマンスの-XX:+UnlockDiagnosticVMOptions -XX:+PrintCompilation -XX:+PrintInlining
メソッドと同様のコンパイルパターンが示されましたが、それがこの問題の根本的な原因ではないと思います。
編集2
-XX:MaxInlineLevel=12
フラグ追加で再現、解決できました。
-XX:MaxInlineLevel=12
以前に省略されたときに問題を再現できなかった理由について、根本的な原因をまだ見つけていません。私が見る限り、同じ設定を使用していました。ラップトップをしばらくアイドル状態にしてから、もう一度ベンチマークを実行してみるかもしれませんが、今のところ、JIT インライン化についての洞察を得られたことに満足しています。
java - 奇妙なオプティマイザーの動作: JVM は 1 つの最適化に固執し、適応しません
2 つの主要な段階がある長いプロセスがあります。第 1 段階と第 2 段階では、実行パスが若干異なります。
-server
JMH ( , on )によると、同じメソッドのコピーを別の名前で作成し、各段階で別の名前を使用するとjava-7-openjdk-amd64
、第 2 段階でメソッド呼び出しが 25% 以上高速化されることに気付きました (メソッドへの数百万回の呼び出し (5 回の呼び出しのウォームアップ後に 5 回の呼び出しで測定)。
メソッドに関する以前の最適化を忘れて、ゼロから再学習するように JVM に指示する方法はありますか?
次のコード例では、ベンチマーク メソッドはであり、とrun
を呼び出す 2 つのバージョン間で比較が行われます。checkChar
checkChar0
stage2
java - Math.log() のデッド コードの削除は、JMH サンプルでどのように機能しますか
JMH フレームワークを利用して意味のあるテストを作成しようとする人は誰でも、JMH サンプル テスト ( http://hg.openjdk.java.net/code-tools/jmh/file/tip/jmh-samples/src/main/java /org/openjdk/jmh/samples/ )。それらを調べていくと、デッド コードの削除 (JMHSample_08_DeadCode.java) に行き詰まりました。
抜粋:
measureWrong() の測定値は、ベースライン テストとほぼ同じになります。Math.log() の戻り値は使用されないためです。したがって、HotSpot コンパイラはデッド コードを排除します。了解しましたが、コンパイラは Math.log() を削除できるとどのように判断できますか。
テストを詳しく見てみると、Math.log() がネイティブ メソッドであることがわかります。そして、ネイティブ呼び出しは OS に行き、対応するライブラリを実行します。右?これにより、戻り値が使用されず、io 操作が実行されない場合、ネイティブ呼び出しがコンパイラによって削除される可能性があるという仮定が導かれます。
OS のどこかに常駐し、Java ワールドからのネイティブ呼び出しを処理する lib が戻り値を提供せずに io 操作 (ロギングなど) を行うとしたらどうでしょうか。それらの指示は完全に消去されますか?
仮定を証明するために、単純な JMH テストとネイティブ コールを使用してシナリオを再構築しました。実行する 3 つの C ネイティブ ライブラリをコンパイルしました。
- 返す 42
- パラメータ追加
- 空のファイルの作成
JMH テスト (measureWrong() テストと同様) でそれらを呼び出したので、io 操作を実行しないものでさえも、どれも削除されていません。テスト結果により、私たちの仮定は確認できません。ネイティブ呼び出しを最適化することはできません。つまり、Math.log() とカスタム ネイティブ呼び出しは同じ基準を持っていません。彼らは同じようにネイティブではありません。おそらく、ネイティブの lib コードに誤りがあり、少なくともテスト 1 のネイティブ コールは削除されているはずです。これが正しい場合は、コードを共有します。
そのため、さらに検索した結果、Java コードが、アーキテクチャの非常に最適化されたコードに対応するものに置き換えられる、組み込み関数という用語を見つけました。java.lang.Math.log() には、そのような組み込みの実装があります。ネイティブとイントリンシックの間に何か関係はありますか? 上記のネイティブとイントリンシクスの関係の仮定が有効である場合、コンパイラはネイティブ呼び出しを排除するために次の手順を実行しますか?
- コンパイル時に、HotSpot は Math.log() の組み込み実装 (jdk?) の存在をチェックし、Math.log() をそのコードに置き換えます。
- その後、HotSpot がメソッドの戻り値を確認する 2 番目のチェックが行われます。この結果で、HotSpot は Math.log() 呼び出しを完全に排除することを決定します。
java - 作業が異なるスレッドによって実行される場合、JMH でスループットをベンチマークする方法は?
複数のスレッド (プロデューサー) が単一の ConcurrentHashMap に書き込むアプリケーションの一部をベンチマークする方法がわかりません。さらに、特定のサイズに達すると、1 つのコンシューマー スレッドがマップを空のマップに切り替えます。プロデューサー スレッドは、追加の輻輳なしでできるだけ速くマップに書き込む必要があるため、マップの切り替えが必要です。コンシューマ スレッドは、マップの要素も処理し、バッファに格納します。最後に、別のスレッドがバッファーの内容をアプリケーションの他のコンポーネントに送信します。
要素が送信される準備が整うまで (-> 集約されたスループット)、要素が ConcurrentHashMap に書き込まれるのにかかる時間 (および対応するスループット) を測定する方法は不明です。今のところ、物事を簡単にするために要素の送信を除外しています。マップ サイズによってスループットが抑制されることがわかっています。ただし、将来の実装のスループットと比較するために測定したいと考えています。
これまでに、次のシナリオを調査しました。
サイロ テスト
このベンチマークは、1 つのベンチマーク内の各ステップを測定します。ベンチマーク A: サイズ (= batchSize) に達するまで要素を Map に挿入します。ベンチマーク B: 要素がバッファに格納されるのにかかる時間を測定します。
利点: 比較的簡単に実現できます。
欠点: ベンチマーク A と B を加算すると、スレッドの対話性が失われ、スループットの集計が得られない。
Flat-Test
Silo-Test と比較して、すべてのステップが 1 つのベンチマーク (シングル スレッド) 内で実行されます。最初に X 要素が Map に挿入され、次に Map が切り替えられ、X 要素が処理されてバッファに格納されます。
利点: 比較的簡単に実現できます。
欠点: スレッドの対話性が失われ、ベンチマークは 1 つのスレッド (-> 1 つのプロデューサーのみ) でしか実行できません。現在の実装では、マップの切り替えと要素の同時処理がサポートされていないためです。
Dynamic-Amount-Test (優先テスト)
ベンチマーク メソッドは、呼び出しごとに 1 つの要素をマップに挿入します。コンシューマー スレッドは @Setup フェーズで開始され、テスト中に要素をバッファーに配信します。ベンチマークの最後に、ベンチマーク メソッドの呼び出しを使用する代わりに、バッファ内の収集された要素の数が結果計算のために JMH に提供されます。ベンチマークの最後にバッファ サイズを JMH に提供できる、すぐに使用できる機能については認識していません。ほとんどの場合、この要件のために JMH を変更する必要があります (そうですか?)。
利点: 合成スループットは JMH によって計算されます
欠点: すぐに使える機能はありません。JMH の変更は危険な場合があります (測定に影響があり、ベンチマークの有効性が不明です)。
補足事項: このシナリオでは、非定常状態のベンチマークにも対処する必要があります。JMH のバッチ処理の可能性を利用して、さまざまなサイズでテストすることを考えました。
建設的な回答をお寄せいただきありがとうございます。