1) は、DLL 関数の呼び出しが常に追加の間接ジャンプを使用しているという事実に基づいています。今日、これは通常、無視できる程度です。DLL の内部では、位置に依存しないコードを生成できないため、i386 CPU にはさらにオーバーヘッドがあります。amd64 では、ジャンプはプログラム カウンターを基準にすることができるため、これは大きな改善です。
2) これは正しいです。プロファイリングによって導かれる最適化により、通常、約 10 ~ 15% のパフォーマンスを獲得できます。CPU 速度が限界に達したので、実行する価値があるかもしれません。
追加します: (3) リンカは関数をよりキャッシュ効率の高いグループに配置できるため、高価なキャッシュ レベルのミスが最小限に抑えられます。また、特にアプリケーションの起動時間に影響を与える可能性があります (Sun C++ コンパイラで見た結果に基づく)
また、DLL ではデッド コードの削除を実行できないことを忘れないでください。言語によっては、DLL コードも最適でない場合があります。クライアントが仮想関数を上書きしているかどうかをコンパイラが認識できないため、仮想関数は常に仮想です。
これらの理由から、DLL が本当に必要ない場合は、静的コンパイルを使用してください。
EDIT(コメントに答えるには、ユーザーのアンダースコアで)
これは、位置に依存しないコードの問題に関する優れたリソースですhttp://eli.thegreenplace.net/2011/11/03/position-independent-code-pic-in-shared-libraries/
説明したように、x86 には 15 ビットのジャンプ範囲以外には AFAIK がなく、無条件のジャンプや呼び出しには対応していません。そのため、32K を超える関数 (ジェネレーターからの) は常に問題であり、埋め込みトランポリンが必要でした。
gcc
しかし、Linux のような一般的な x86 OS では、スイッチ-fpic
(間接ジャンプ テーブルの使用を強制する) を使用して .so/DLL ファイルが生成されなくても気にする必要はありません。そうしないと、コードは通常のリンカーが再配置するように修正されるだけです。しかし、これを行っている間、コードセグメントを共有できなくなり、コードをディスクからメモリに完全にマッピングし、使用する前にすべてに触れる必要があります (ほとんどのキャッシュを空にし、TLB をヒットする) など。これが遅いと考えられたとき。
したがって、あなたにはもう何のメリットもありません。
-fPIC
どの OS (Solaris または FreeBSD) で Unix ビルド システムに問題が発生したか覚えていませんgcc
。