反復処理の速度の最適化

問題を報告 ソースを表示

このページでは、Bazel を繰り返し実行したときに Bazel のビルド パフォーマンスを最適化する方法について説明します。

Bazel の実行状態

Bazel の呼び出しには、相互に関連する複数の部分が含まれます。

  • bazel コマンドライン インターフェース(CLI)はユーザー向けのフロントエンド ツールで、ユーザーからコマンドを受け取ります。

  • CLI ツールは、個別の出力ベースごとに Bazel サーバーを起動します。Bazel サーバーは一般的に永続的ですが、リソースを浪費しないように、アイドル状態になるとシャットダウンします。

  • Bazel サーバーは、特定のコマンド(buildruncquery など)の読み込みと分析のステップを実行し、ビルドグラフの必要な部分をメモリに構築します。生成されるデータ構造は、分析キャッシュの一部として Bazel サーバーに保持されます。

  • Bazel サーバーは、アクションの実行もできます。また、リモート実行が設定されている場合は、アクションを送信してリモート実行にすることもできます。アクション実行の結果もアクション キャッシュ(または、ローカルまたはリモートの実行キャッシュ)にキャッシュされます。これは、Bazel サーバー間で共有される場合があります。

  • Bazel の呼び出し結果が出力ツリーで利用できるようになります。

Bazel を反復的に実行する

一般的なデベロッパー ワークフローでは、コードの一部を繰り返しビルド(または実行)し、多くの場合、非常に高い頻度でビルド(または実行)します(コンパイル エラーの解決やテストの失敗の調査など)。この状況では、bazel の繰り返し呼び出しが、基礎となる繰り返しのアクション(コンパイラの呼び出しやテストの実行など)と比べてオーバーヘッドをできる限り小さくすることが重要です。

このことを念頭に置いて、Bazel の実行時の状態を再確認します。

分析キャッシュは重要なデータです。コールドランの読み込みフェーズと分析フェーズ(Bazel サーバーが起動された直後や分析キャッシュが破棄されたときなど)にのみ、かなりの時間が費やされることがあります。このコストは、成功した単一のコールドビルド(製品版リリースなど)であれば許容できますが、同じターゲットを繰り返しビルドする場合は、このコストを平均化し、呼び出しごとに繰り返さないことが重要です。

分析キャッシュはかなり不安定です。まず、これは Bazel サーバーのインプロセス状態の一部であるため、サーバーが失われるとキャッシュが失われます。ただし、キャッシュは非常に簡単に無効化されます。たとえば、多くの bazel コマンドライン フラグが原因でキャッシュが破棄されます。これは、多くのフラグが(構成可能な属性などのために)ビルドグラフに影響するためです。フラグの変更によっては、Bazel サーバーが再起動されることもあります(起動オプションの変更など)。

優れた実行キャッシュは、ビルドのパフォーマンスにも影響します。実行キャッシュは、ローカルのディスク上またはリモートに保存できます。キャッシュは Bazel サーバー間で、実際はデベロッパー間で共有できます。

分析キャッシュを破棄しない

分析キャッシュが破棄された場合、またはサーバーが再起動された場合、Bazel は警告を出力します。繰り返し使用するときは、次のいずれかを避ける必要があります。

  • 反復的なワークフローの途中で bazel フラグを変更するように注意してください。たとえば、bazel build -c optbazel cquery を混在させると、各コマンドが互いの分析キャッシュを破棄します。通常は、特定のワークフローの期間中に固定されたフラグのセットを使用するようにします。

  • Bazel サーバーを停止すると、分析キャッシュが失われます。Bazel サーバーには構成可能なアイドル時間があり、この期間を過ぎるとシャットダウンします。この時間は、必要に応じて bazelrc ファイルで構成できます。起動フラグが変更されるとサーバーが再起動するので、これらのフラグも可能な限り変更しないようにします。

  • Bazel の実行中に Ctrl+C を繰り返し押すと、Bazel サーバーが強制終了されることに注意してください。不要になったビルドを中断して時間を節約しようとしますが、Ctrl+C を 1 回押すだけで、現在の呼び出しの正常な終了をリクエストします。

  • 同じワークスペースから複数のフラグセットを使用する場合は、複数の個別の出力ベースを使用し、--output_base フラグを使用して切り替えます。各出力ベースは独自の Bazel サーバーを取得します。

この条件を警告ではなくエラーにするには、--noallow_analysis_cache_discard フラグ(Bazel 6.4.0 で導入)を使用します。