「CreateObject」以外の機能を公開しないライブラリがあります。それにもかかわらず、それらの関数はすべて間接的に呼び出されるため、パフォーマンス レポートでは、最大 1.65% の時間が __i686.get_pc_thunk.bx に費やされていることがわかります。関数 (クラス メソッド) は 1 億 6000 万回呼び出され、共有ライブラリの内部にあり、公開されていません。
再配置なしで内部メソッドをコンパイルできるかどうか、つまり、相対オフセットなどを使用できるかどうか疑問に思います。
gcc は 4.5.2 です
更新: 実際には、メイクファイルに残っている -O0 が原因だと思います。今は大したことではありませんが、プロファイラーの「ガベージ」が少なくなるので、-O0 でも同じことをしたいと思います。これを行う -O2 「本当の」オプションは何ですか。
更新 2: うーん、-O2 ではなく、おそらく --dynamic-list が pc_thunk のパフォーマンス ヒットを少し下げましたが、まだ残っています... そのため、--dynamic-list が本当に役立つかどうかさえわかりません。非表示のシンボルに間接サンクを含める必要がありますか?それは正しいですか?
更新 3: テスト プロジェクトを作成しました。内部ライブラリ関数の属性の可視性を非表示に設定し、gcc 4.7 および -O2 と LTO を有効にしてコンパイルし、内部関数を含めずに --dynamic-list をリンカーに渡しましたが、それでも呼び出しget_pc_thunk にはまだあります。
これはテスト共有ライブラリのコードです:
#include <stdio.h>
__attribute__((visibility("hidden"), noinline)) void lib1f2()
{
puts("I should have PLT disabled");
}
void lib1f()
{
puts("I'm lib1");
lib1f2();
}
gdb では、lib1f2 内にまだサンクが表示されます。
面白いのは、 -fwhole-program lib1f2 を使用すると、メインの実行可能ファイルにインライン化されますが、サンクへのこの呼び出しがまだ含まれていることです。
更新 4: OK に近づいています (私が愚かであることを理解するために)。プログラム (および上記のコード) は、単なる const 文字列であってもデータを使用するため、GOT 呼び出しが必要です。したがって、今の質問は次のとおりです。
- それでも、GOT のサンクを回避できますか?
- (関連) おそらく -fPIC なしでコンパイルする - 欠点は何ですか?