よくある質問
プロファイリングにユニット・テストを使用できますか。
可能ですが、通常は推奨されません。ユニット・テストを使用してプロファイルを生成するには、任意のアプリケーションのネイティブ実行可能ファイルを生成するのと同じ方法で、テスト・スイート用にインストゥルメントされたバイナリを生成する必要があります。たとえば、テスト・ハーネスを開始するmain()
メソッドを設定できます。インストゥルメントされたバイナリが実行されると、インストゥルメントされたバイナリと同様に、プロファイルとともにファイルがダンプされます。
プロファイルに基づく最適化の品質は、最適化されるネイティブ・ビルドへの入力として提供するプロファイルの品質に依存することに注意してください。テストが本番で実行されるワークロードを正確に表していることを確認する必要があります。一般に、次の理由から、それを保証するのは簡単ではありません:
- ユニット・テストは、コンポーネントのすべてのコーナー・ケースをテストするように設計されており、その多くは実際には一般的ではありません(つまり、テストして正しく動作する必要があるが、コードのコーナー・ケースは通常高速である必要はありません)。
- コードの異なるコンポーネントが、常に同じ数のユニット・テストで表されるとはかぎりません。ユニットテスト・スイートに基づくプロファイルは、1つのコンポーネントの重要性を過剰に表し、ほかのコンポーネントの重要性を過小評価する場合があります。
- ユニットテスト・スイートは、テストが追加され、時間の経過とともに進化します。今日アプリケーションの動作を正確に表しているものでも、明日は正確に表していない可能性があります。
たとえば、静的コンテンツを提供するWebサーバーを実装しているとします。ほとんどの場合、Webサーバーはディスクまたはインメモリー・キャッシュからファイルを読み取り、そのファイルを圧縮して、ネットワーク経由で圧縮バイトを送信します。ただし、適切なユニットテスト・スイートは、構成ファイルの解析、キャッシュの無効化、リモート・デバッグのコードなど、Webサーバーのすべてのコンポーネントをテストします。このコードは、Webサーバーの通常の実行中にほとんど実行されないかまったく実行されない可能性があります。すべてのユニット・テストでプロファイルを収集すると、実際にはほとんど実行されないコードの一部が過剰に反映され、コンパイラの最適化が誤ったものになります。
結論としては、可能ですが、ユニット・テストをプロファイルとして使用することはお薦めしません。これは、ユニット・テストがアプリケーションの処理をどの程度適切に表すかは明確ではないためです。かわりに次のことをお薦めします:
- 重要な本番ワークロードを表すエンドツーエンド・テストのサブセットを識別します。エンドツーエンドのテストは、アプリケーションが本番環境で何をするかをシミュレートし、コード内のどこでどのように時間が費やされるかを正しく表す可能性が高いです。前述のWebサーバーの例では、エンドツーエンドのテストでWebサーバーを起動し、様々なURLを取得するために数千のリクエストを送信してから、サーバーを停止します。
- または、本番環境でのアプリケーションの動作を表すベンチマーク・ワークロードを作成します。優れたベンチマークには、典型的なワークロードの特性が組み込まれます。前述のWebサーバーの例では、現実的なベンチマークには、Webサーバーが本番で実行されているときに確認されたリクエストの分散が組み込まれます。つまり、ベンチマークは、本番環境で特定のサイズのファイルが要求された頻度、およびファイルの圧縮率をモデル化します。
PGOプロファイルは十分にクロス・プラットフォームですか。それとも各ターゲットを個別にインストゥルメントする必要がありますか。
はい。ほとんどの場合、PGOプロファイルは十分にクロスプラットフォームです。あるプラットフォームでインストゥルメントされたバイナリを実行してプロファイルを収集し、そのプロファイルを使用して別のプラットフォームで最適化されたネイティブ実行ファイルをビルドできます。
バイナリがビルドされたプラットフォームによっては、ネイティブ・イメージで異なるクラスおよびメソッドが使用される場合があります。たとえば、PosixProcessPropertiesSupport
クラスにはPOSIXベースのシステムでプロセスを操作するコードが含まれ、WindowsProcessPropertiesSupport
クラスにはWindowsでプロセスを操作するコードが含まれます。同様に、JDKの一部にはプラットフォーム固有のコードが含まれています。このような場合、プロファイルにはあるプラットフォーム用のエントリが含まれますが、最適化されたネイティブ・ビルドでは、そのプラットフォーム固有のコードのプロファイル・エントリは検出されません。このようなコーナー・ケースはまれであり、通常はパフォーマンスへの影響はありませんが、注意が必要です。
結論として、ベスト・プラクティスは常に、最適化されるネイティブ実行可能ファイルのターゲットと同じプラットフォーム上のプロファイルを収集することです。しかし、異なるプラットフォームで収集したプロファイルを使用しても、通常はうまく機能します。
プロファイリング情報は、コードの変更が限定的なものであれば、変更後再利用できますか。それとも、ビルドごとに新しいプロファイリング情報を収集する必要がありますか。
はい。プロファイリング情報は常に再利用でき、ネイティブ実行可能ファイルが正しく生成されるはずです。ビルドごとに新しいプロファイリング情報を収集する必要はありません。
ただし、最適化されたネイティブ実行可能ファイルのパフォーマンスへの影響は、プロファイルの品質に依存することに注意してください。プログラムの新しいコードが、プロファイルが収集されたコードと大幅に異なる場合、コンパイラの最適化でどのコードが重要なのかが見誤られます。コードの変更が十分に小さいか、プログラムのコールド部分に限定されている場合、古いプロファイルを使用しても最適化されたネイティブ・バイナリのパフォーマンスが低下することは通常ありません。
このトピックの詳細は、「プロファイルの品質の追跡」のガイドラインを参照してください。
インストゥルメントされたバイナリを使用してベンチマークを実行することもできますか。
はい、インストゥルメントされたバイナリは、ベンチマークを含む任意のプログラムに対して生成できます。実際、プロファイルを収集するには、代表的なベンチマークを使用してプロファイルを収集することをお薦めします。
インストゥルメンテーションのオーバーヘッドにより、通常、インストゥルメントされたバイナリはデフォルト(インストゥルメントされていない)ネイティブ実行可能ファイルより遅くなります。インストゥルメンテーションのオーバーヘッドを最小限に抑えるために継続的に努力していますが、インストゥルメントされたバイナリが遅くなり、実行するアプリケーションのコード・パターンによって変わる可能性があります。
また、ベンチマークは、本番環境で予想されるワークロードを表すことが理想的です。ベンチマークのワークロードが本番ワークロードに対応すればするほど、PGOが最適化されたネイティブ・ビルドのパフォーマンスにプラスの影響を与える可能性が高くなります。
結論として、ベンチマークが本番で実行するワークロードを正確に表す場合は、インストゥルメントされたベンチマーク・バイナリのプロファイルを収集し、その後、これらのプロファイルを使用して本番ワークロード用に最適化されたネイティブ実行可能ファイルをビルドすることをお薦めします。
GraalVMは、Webアプリケーションをプロファイリングするためのワークロードをどのように生成しますか。
GraalVM自体は、ネイティブ・イメージでコンパイルされたWebアプリケーションをプロファイリングするためのワークロードを生成しません。かわりに、ロード・テスト・ツールを使用してワークロードを生成する必要があります。
たとえば、Webアプリケーションが複数のHTTPエンドポイントを公開する場合、wrk
などのロード・テスターを使用して、それらのHTTPエンドポイントへのリクエストのストリームを生成する必要があります。この設定は次のようになります。Webアプリケーションのインストゥルメントされたバイナリをビルドし、あるプロセスで起動し、別のプロセスでwrk
などのロード・テスターを起動します。ロードテストの期間は、本番環境で発生すると予想されるリクエスト・ペイロードを使用して、本番ユーザーが最も頻繁にアクセスするWebアプリケーションのエンドポイントを実行するのに十分な長さである必要があります。単純なWebアプリケーションの場合、通常、1分の期間は良質のプロファイルを生成するのに十分です(ただし、これは特定のアプリケーションによって異なります)。ロードテストが完了し、Webアプリケーションが終了すると、プロファイルがファイルにダンプされます。
しばらくの間、本番環境でプロファイルを収集するのはどうですか。たとえば、サービスの1つのインスタンスでのみ月曜日の8:00から12:00まで収集します。
それはプロファイルを収集する良い方法です。
インストゥルメントされたバイナリには、特定のアプリケーションのコード・パターンに依存する特定のオーバーヘッドがあります。ただし、特定の期間にインストゥルメントされたバイナリを1つのインスタンスのみが使用し、サービスの他のすべてのインスタンスが通常またはPGO最適化ビルドを使用する場合、これは実際には一般的に許容されます。
このトピックの詳細は、「プロファイルの品質の追跡」のガイドラインを参照してください。