Google Propellerは、実行時の動作のプロファイルに基づいてLLVMバイナリを再リンクおよび最適化することにより、LLVMバイナリのパフォーマンスを向上させることができる。Googleのエンジニアによると、Propellerは、以前はLLVMによって高度に最適化されていたバイナリの主要なパフォーマンスベンチマークを2~9%向上させることができる。
Propellerの目的は、自身でプロファイルしたバイナリに対して、レイアウトに何回かの変換を適用して、新しいバイナリを作成することである。つまり、Propellerを利用するために実施することは、プログラムを実行し、特定のフラグを使用してコンパイルし、実行時の動作とパフォーマンスに関するメトリックを収集することである。次に、そのデータをPropellerに与え、最大のパフォーマンスを引き出すためにバイナリレイアウトを変換する。これは、プロファイルに基づく最適化と呼ばれるものであり、実行時にシステムを最適化するDynamoや、その他の類似のツールによって提供される動的最適化と混同しないでください。
2019年9月にLLVM-devメーリングリストで最初に発表されたPropellerはFacebook BOLTにインスピレーションを受けたものである。Facebook BOLTは、最近は、別のLLVMベースのプロファイルベースのリリンカーである。ただし、Propellerは、分散ビルドシステムでの使用に適した別のアプローチを使用し、そのバイナリサイズに対して、より適切にスケーリングする。
特に、Googleのエンジニアは、BOLTは実行時のパフォーマンスを大幅に向上させるが、モノリシックなシングルステップアーキテクチャにより、セグメントサイズが300 MB以下のバイナリに対して必要なメモリと時間が急増することに気付いた。現在、300MBのバイナリは確かに大きく、多くの開発者がそのような大規模なシステムを最適化する必要はないかもしれないが、PropellerはBOLTに比べていくつかの追加の利点を提供するようである。具体的には、Propellerは2段階の最適化プロセスを中心に設計されており、最初のステップは並列ワーカー全体に分散できる。これとは対照的に、BOLTは、一度に入力バイナリを直接処理する単一のプロセスとして実装される。
さらに、PropellerはインクリメンタルビルドについてBOLTよりもはるかに優れているであろう。これは、小さなソースの変更によってプロファイル情報が大幅に変更されない場合に有効である。Propellerは、再処理する必要のあるバイナリの部分を特定するのにより適切に機能する。Googleのエンジニアによると、BOLTを使用すると、プロファイルを少し変更しただけでもプロファイルが無効になるため、最適化プロセスを完全に再実行する必要がある。
全体的に見ると、LLVMは他の主要なコンパイラーとともに、リンク時最適化(LTO)とプロファイルに基づく最適化(PGO)の両方をすでに実行できる。BOLTやPropellerのようなツールがLLVM最適化をさらに改善するために行うことは、プロファイルデータのより積極的な使用であり、近似よりも正確なプロファイルデータの使用を優先する。
Propellerの仕組みの詳細に興味がある場合、Googleは、どのようにPropellerが動作するかを全面的に文書化したRFC(PDF)と、GitHubからソースコードをプルしてコンパイルするところから始まるどうやって使うかを提供している。