2009-10-13 12 views
5

私は実際に何をしているのかと期待できるはるかに大きなコードを生成するC++ライブラリを持っています。 50K以下のソースからは、ほぼ4MBの共有オブジェクトと9個の静的アーカイブが得られます。これは、ライブラリバイナリがかなり大きく、さらに悪いことに、単純なアプリケーションでも500〜1000 KBのコードサイズ。 -Oのようなフラグを使ってライブラリをコンパイルすると、これはいくらか助けになりますが、実際はそれほど役に立ちません。C/C++アプリケーションで過剰なコードサイズをプロファイリングするためのテクニックやツールは何ですか?

私はGCCの-frepoコマンドを使って実験しました(Linux collect2が重複したテンプレートをマージすることを示唆しているすべてのドキュメントでも)と、 "重複する可能性が高い"どちらの場合でも実際の効果はありません。もちろん、私は「可能性が高い」と言っています。何らかのプロファイリングのように、このような盲目の推測はほとんど常に間違っているからです。

コードサイズのプロファイリングを容易にするツールがありますか、それで何がすごく多くの部屋を占めているのか、もっと一般的には、私が試してみるべきことが分かりますか? Linux上で動作するものは理想的ですが、私が得ることができるものを取り上げます。

答えて

7

実行可能ファイルに何が入っているのかを知りたい場合は、ツールに質問してください。 ldリンカーの--print-map(または-M)オプションをオンにして、メモリに格納された内容と場所を示すマップファイルを生成します。これは、静的リンクされた例ではおそらくより有益です。

gcコマンドラインからのみldを直接呼び出すのではない場合は、ldに固有のオプションをgcコマンドラインから-Wl,の前に付けて渡すことができます。

+0

「-W1」ではない、「-Wl」 –

+0

@FX - ありがとうございます。私はそれを修正しました。 –

1

非常に粗いが非常に速い方法の1つは、オブジェクトファイルのサイズを調べることです。オブジェクトファイルのすべてのコードが最終的なバイナリにコンパイルされるわけではありませんので、いくつかの誤検出があるかもしれませんが、ホットスポットがどこにあるかについての良い印象を与えることができます。最大のオブジェクトファイルを見つけたら、とnmのようなツールを使ってそれらのファイルを調べることができます。

2

Linuxでは、リンカは確かに複数のテンプレートのインスタンシエーションをマージします。

デバッグバイナリを測定していないことを確認してください(デバッグ情報は最終バイナリサイズの75%以上を占める可能性があります)。

最後のバイナリサイズを減らす1つの方法は、-ffunction-sections-fdata-sectionsでコンパイルし、次に-Wl,--gc-sectionsとリンクすることです。

さらに大きな削減(当社が25%を見てきました)あなたは-Wl,--icf

別の有用な技術であると開発[gold][1]のバージョン(新しいELF専用リンカ、binutilsの一部)、およびリンクを使用している場合は可能かもしれません__attribute__((visibility(...)))を介して、またはリンカースクリプトを使用して、共有ライブラリ(すべてはデフォルトでエクスポートされます)によって「エクスポート」されたシンボルのセットを減らします。詳細here(「エクスポートコントロール」を参照)。