4

開発者がすべての h および c ファイルを ac ファイルに含めるオプションを選択した組み込みプロジェクトを整理しようとしています。その後、-whole-program オプションを使用してその 1 つのファイルだけをコンパイルして、適切なサイズの最適化を得ることができます。

私はこれが嫌いで、これを LTO を使用して同じことを達成する従来のプログラムにすることを決意しています。

開発キットに含まれるバージョンは次のとおりです。aps-gcc (GCC) 4.7.3 20130524 (Cortus) GNU ld (GNU Binutils) 2.22

1 つの .o ファイルの .text は 0x1c7ac で、67 個の .o ファイルに分割されます。

--gc-sections を試し、リンカー プラグイン オプションを使用しましたが、それ以上の改善はありませんでした。

何か提案がありますか? LTO から適切な改善が見られますか?

4

2 に答える 2

0

LTO を完全に機能させるには、コンパイル段階と同じ情報と最適化アルゴリズムをリンク段階で利用できるようにする必要があります。GNU ツールはこれを行うことができず、これが実際に LLVM/Clang を作成する動機の 1 つになったと私は信じています。

違いを詳細に調べたい場合は、オプションごとに Map ファイル ( ldoption -Map <filename>) を生成し、インライン化されていない関数やより大きな関数があるかどうかを確認することをお勧めします。関数の定義をヘッダーファイルに移動し、それextern inlineを効果的にマクロに変換するように定義することにより、これらの関数を強制的にインライン化することにより、インライン化の欠如を手動で解決できます (これは GNU 拡張です)。

より大きな関数は、一定の伝播の影響を受けない可能性が高く、それについてできることは何もないと思います。const、、、、などの関数属性を慎重に宣言することで、いくつかの改善を行うことがleafできます。これらは、単一のコンパイル単位を使用している場合にコンパイラが検出する可能性のある特定の方法で関数が動作し、追加の最適化を可能にすることを効果的に約束します。noreturnpurereturns_nonnull

対照的に、Clang はオブジェクト コードを特別な種類のバイトコードにコンパイルし (LLVM は Low Level Virtual Machine の略で、JVM は Java Virtual Machine のように、バイトコードを実行します)、このバイトコードの最適化をリンク時に実行できます (または、実際にはクールなランタイム)。このバイトコードは、LTO を使用するかどうかに関係なく最適化されるものであり、最適化アルゴリズムはコンパイラとリンカーの間で共通であるため、理論的には、LTO を使用するかどうかにかかわらず、Clang/LLVM はまったく同じ結果を返すはずです。

残念ながら、C バックエンドが LLVM から削除されたので、ターゲットにしているカスタム CPU に LLVM LTO 機能を使用する方法がわかりません。

于 2015-10-15T23:15:58.267 に答える
0

私の意見では、以前の開発者が選択した方法は正しいものです。これは、コンパイラに最も多くの情報を提供する方法であり、したがって、必要な最適化を実行する機会が最も多くなります。これはコンパイルするのにひどい方法です (変更を加えると、プロジェクト全体をコンパイルする必要があります)。

もちろん、そのようなビルドに対してすべての統合テストを実行する必要がありますが、それは簡単なことです。コンパイル時間を除いて、選択したアプローチの欠点は何ですか (常にそのようにビルドする必要はないため、問題にはならないはずです... 統合テストのためだけに)。

于 2015-10-15T23:39:05.473 に答える