2

PIC (位置独立コード) としてコンパイルすると 70 ~ 80% 遅くなるコードを扱っており、問題を軽減する方法を探しています。問題の大部分は、gcc がすべての単一関数に以下を挿入することを主張していることです。

call __i686.get_pc_thunk.bx
addl $_GLOBAL_OFFSET_TABLE_,%ebx

それが関数の内容の 20% になったとしても。現在、ebxは呼び出し保存レジスタであり、関連する変換単位 (ソース ファイル) 内のすべてstaticの関数が GOT のアドレスをロードしており、変換単位の外部から関数を呼び出すことができないことを簡単に検出できます (それらのアドレスは取ったことはない)。では、なぜ gcc は大きな外部リンケージ関数の最初に 1 回だけロードして、GOT のアドレスが既にロードされているebxと想定するように静的リンケージ関数を生成できないのでしょうか? ebxすべてが外部関数にインライン化されるようにインライン制限を非常に高くする以外に、gcc にこの明白で大規模な最適化を強制するために使用できる最適化フラグはありますか?

4

2 に答える 2

3

おそらくこれに対する一般的な解決策はありませんが、インライン化オプションをいじってみることができます。staticコンパイル ユニット内の関数の呼び出し元はそれほど多くないので、コード レプリケーションのオーバーヘッドはそれほど大きくないと思います。

gcc でそのようなことを強制する最も簡単な方法は、attribute((always_inline)). 移植性を確保するために、gcc 依存マクロをいじることができます。

コードを変更したくない場合 (ただし、変更しても問題ありませんstatic inline)、オプションを使用し-finline-limitて微調整することができます。

于 2011-02-22T08:46:53.433 に答える
1

実際には解決策ではありませんが、問題の関数がファイルスコープ変数を参照しない場合は、それらをすべて単一の翻訳単位にまとめて、-fPIC フラグなしでコンパイルできます。次に、通常どおり、最終的な SO でそれらを他のファイルと一緒にリンクします。

于 2011-02-22T10:14:59.767 に答える