MPEGデコーダーでいくつかの最適化を行っています。最適化によって何も壊れていないことを確認するために、コードベース全体(最適化されたものとオリジナルの両方)をベンチマークするテストスイートがあり、両方が同じ結果を生成することを確認します(基本的にはデコーダーとcrc32を介していくつかの異なるストリームをフィードするだけです)出力)。
Sun 1.6.0_18で「-server」オプションを使用すると、ウォームアップ後の最適化されたバージョンでのテストスイートの実行が(デフォルトの「-client」設定と比較して)約12%遅くなりますが、元のコードベースは大幅に向上します。クライアントモードの約2倍の速度で実行されます。
最初はこれは単なるウォームアップの問題のように見えましたが、テストスイート全体を複数回繰り返すループを追加しました。その後、テストの3回目の反復から開始する各パスの実行時間は一定になりますが、最適化されたバージョンはクライアントモードよりも12%遅くなります。
また、コードには起動後のオブジェクトの割り当てがまったく含まれていないため、ガベージコレクションの問題ではないと確信しています。このコードは、主にいくつかのビット操作操作(ストリームデコード)と多くの基本的な浮動演算(PCMオーディオの生成)で構成されています。関連するJDKクラスは、ByteArrayInputStream(ストリームをテストにフィードし、ディスクIOをテストから除外する)とCRC32(結果を検証するため)のみです。また、Sun JDK 1.7.0_b98でも同じ動作が見られました(12%ではなく15%でした)。ああ、テストはすべて同じマシン(シングルコア)で行われ、他のアプリケーションは実行されていません(WinXP)。(System.nanoTime btwを使用して)測定された実行時間には避けられない変動がありますが、同じ設定での異なるテスト実行間の変動は2%を超えることはなく、通常は1%未満(ウォームアップ後)です。
サーバーJITでパフォーマンスが低下する既知のコーディングパターンはありますか?それができない場合、内部を「覗き見」してJITがそこで何をしているのかを観察するために利用できるオプションは何でしょうか。
たぶん、「ウォームアップ」の説明を間違って言いました。明示的なウォームアップコードはありません。テストスイート全体(12の異なるmpegストリームで構成され、合計で最大18万のオーディオフレームを含む)が10回実行され、最初の3つの実行は「ウォームアップ」と見なされます。私のマシンでは、1回のテストラウンドで100%CPUが約40秒かかります。
提案されたようにJVMオプションを試して、「-Xms512m -Xmx512m -Xss128k -server -XX:CompileThreshold = 1 -XX:+ PrintCompilation -XX:+ AggressiveOpts -XX:+PrintGC」を使用してすべてのコンパイルがで行われることを確認できました最初の3ラウンド。ガベージコレクションは3〜4ラウンドごとに開始され、最大で40ミリ秒かかります(テストは16メートルで問題なく実行できるため、512メートルは非常に特大です)。このことから、ガベージコレクションはここでは影響がないと結論付けます。それでも、クライアントとサーバーを比較すると(他のオプションは変更されていません)、12/15%の違いが残っています。