シンボル・プリエンプションまたは位置に依存しないコードが不要なアプリケーションは、汎用の ABI 可視属性を利用してパフォーマンスを向上させることができます。
グローバルシンボルは、宣言されたコンパイル単位 (インクルード・ファイルに関連する単一ソースファイル) の外部で見えるシンボルです。コンパイル単位中の各グローバルシンボル定義や参照には、それらが定義されたコンポーネントの外部からどのように参照されるかを制御する可視属性があります。
可視属性の値は次のトピックで定義および説明されています。
-fvisibility コンパイラー・オプション
可視性は参照と定義の両方に適用されます。シンボル参照の可視属性は、対応する定義にその可視属性が適用されることを意味します。
共有可能なオブジェクトの関数やデータ項目を使用するときに、それらの代わりに独自に定義したものを使用することができます。例えば、アプリケーションが標準のランタイム・ライブラリーの共有可能なオブジェクト libc.so を使用するときに、独自のヒープ管理ルーチン malloc および free の定義を使用することができます。
この場合、libc.so 内での malloc および free への呼び出しが、libc.so にある定義ではなく独自のルーチンの定義を呼び出すことが重要です。独自の定義は、共有可能なオブジェクト内の定義を無効に (プリエンプト) します。
このように共有オブジェクトの項目を再定義する機能は、シンボル・プリエンプションと呼ばれます。ランタイムローダーがコンポーネントをロードするとき、コンポーネント内の default 可視属性のシンボルはすべて、すでにロードされているコンポーネント内の同じ名前のシンボルによるプリエンプションに従います。ただし、メインプログラムのイメージは常に最初にロードされるので、メインプログラムが定義するシンボルがプリエンプト (つまり再定義) されることはありません。
default 可視属性のシンボルは実行時までメモリーアドレスにバインドされないため、シンボル・プリエンプションが発生する可能性により多くのコンパイラーの最適化は禁止されます。例えば、default 可視属性のルーチンへの呼び出しは、コンパイル単位が共有可能なオブジェクトにリンクされた場合にプリエンプトされるため、インライン展開することができません。プリエンプト可能なデータシンボルは、名前が異なるコンポーネント中のシンボルにバインドされるため、GP 相対アドレス指定を使用してアクセスすることはできません。GP 相対アドレスはコンパイル時にはわかりません。
シンボル・プリエンプションは、コンパイラーの最適化と全く逆の効果であるため、ほとんど使用されていない機能です。この理由のため、コンパイラーはすべてのグローバルシンボル定義をデフォルトでプリエンプト可能ではない (つまり、protected 可視属性) として扱います。別のコンパイル単位で定義されているシンボルへのグローバル参照は、デフォルトでプリエンプト可能である (つまり、default 可視属性) として仮定されます。すべてのグローバル定義や参照をプリエンプト可能にする場合は、このデフォルトを上書きしてください。
インテル® コンパイラーには可視属性オプションが備わっており、可視属性のコマンドライン制御に加え、これらの属性の完全な範囲を設定するソース構文が提供されます。
これらオプションにより、ヘッダーファイルの変更に依存せずに、機能に直接アクセスできるようになります。可視オプションによって指定された可視属性が、すべてのグローバルシンボルに適用されます。シンボルの可視属性を明示的に指定するには、次の 2 つのオプションを使用できます。
例 |
---|
-fvisibility=keyword -fvisibility-keyword= file |
最初の形式は、グローバルシンボルのデフォルトの可視属性を指定します。2 番目の形式は、1 つのファイル内にあるシンボルの可視属性を指定します (この形式は最初の形式を上書きします)。
シンボルファイルを使用しない可視属性の設定
このオプションは、可視属性リストファイルで指定がなく、宣言に VISIBILITY 属性のないシンボルの可視属性を設定します。シンボル・ファイル・オプションが特に指定されない場合、指定した属性がすべてのシンボルに設定されます。コマンドラインの入力例を次に示します。
例 |
---|
icc -fvisibility=protected a.c |
次のコマンドライン・オプションの 1 つを使用してシンボルのデフォルトの可視属性を設定することができます。
例 |
---|
-fvisibility=extern -fvisibility=default -fvisibility=protected -fvisibility=hidden -fvisibility=internal |