通常、オブジェクトは特定のアーキテクチャーのすべてのシステム上で実行できるように設計され、構築されています。しかし、各システムが特別の機能を持っていると、多くの場合、最適化の対象となります。最適化されたコードは、前のセクションで説明したメカニズムを使用して、そのコードを実行するために必要とする機能で特定できます。
最適化されたインスタンスを実行したり、テストしたりするには、必要な機能を備えたシステムを使用する必要があります。システムごとに、実行時リンカーは使用可能な機能を判断してから、機能にもっとも対応できるインスタンスを選択します。テストと実験を支援するため、実行時リンカーに対してシステムに備わった機能ではなく機能の代替セットを使用するように指示できます。また、これらの代替機能に対して特定のファイルだけが検証されるようにも指定できます。
機能の代替セットはシステム機能から派生したもので、再度初期化したり、機能を追加または削除したりできます。
環境変数のファミリを使用すると、機能の代替セットを作成したり、その使用対象を設定したりできます。
代替プラットフォームの名前を識別します。
代替マシンハードウェアの名前を識別します。
代替ハードウェア機能の値を識別します。
代替ソフトウェア機能の値を識別します。
代替機能に対して検証すべきファイルを指定します。
機能環境変数 LD_PLATCAP および LD_MACHCAP は、プラットフォーム名とマシンのハードウェア名をそれぞれ定義する文字列を受け入れます。プラットフォーム機能の特定およびマシン機能の指定を参照してください。
機能環境変数 LD_HWCAP および LD_SFCAP は、機能のシンボル表現としてコンマ区切りのトークンリストを受け入れます。ハードウェア機能の特定および ソフトウェア機能の特定を参照してください。トークンには数値も指定できます。CA_SUNW_HW_1 や CA_SUNW_HW_2 など、異なるマスクに対する数値を設定するには、角括弧で囲まれたインデックスを数値の前に指定します。たとえば、LD_HWCAP=[2]0x80 は CA_SUNW_HW_2 を値 0x80 に設定します。インデックスを指定しなかった場合は、1 とみなされます。無効なインデックスは無視されます。
「+」接頭辞を付けると、次に続く機能が代替機能に追加されます。「-」接頭辞を付けると、次に続く機能が代替機能から削除されます。「+-」がないと、次に続く機能が代替機能と置き換わります。
機能を削除すると、エミュレートされる機能環境がより制限されます。一般的に、機能インスタンスのファミリが存在する場合、汎用的で機能に固有でないインスタンスも提供されます。このため、より制限された機能環境を使用すると、機能が少ない、または汎用のコードのインスタンスを使用するように強制できます。
機能を追加すると、エミュレートされる機能環境がより向上します。この環境は慎重に構築する必要がありますが、機能ファミリのフレームワークを実行するために使用できます。たとえば、mapfile を使用すると、期待される機能を定義する関数ファミリを作成できます。これらの関数はprintf(3C)を使用すると、その実行を確認できます。関連オブジェクトの作成を検証したり、さまざまな機能を組み合わせて実行したりできるようになります。関数の実際の機能要件をコーディングする前に、このように機能ファミリをプロトタイピングすると有益です。しかし、ファミリインスタンス内のコードが適切に動作するために特定機能を必要とし、この機能がシステムに備わっていないが代替機能として設定されている場合、このコードインスタンスは正しく動作しません。
LD_CAP_FILES も使用しないで一連の代替機能を作成すると、プロセスのすべての機能固有オブジェクトが代替機能に対して検証されます。この方法も注意深く実行してください。多くのシステムオブジェクトは、正常に動作するために、システム機能を必要とするためです。機能を変更すると、システムオブジェクトが正常に動作しなくなる場合があります。
機能の実験を行うために最適な環境は、オブジェクトで使用するすべての機能を備えたシステムを使用することです。LD_CAP_FILES も使用して、実験するオブジェクトを分離してください。次に、「-」構文を使用して機能を無効にすると、ユーザーのさまざまな機能ファミリのインスタンスを実行できます。各インスタンスは、システムの本物の機能で完全にサポートされます。
たとえば、x86 の 2 つの機能オブジェクト libfoo.so および libbar.so があるとします。これらのオブジェクトには、SSE2 命令を使用するように最適化された機能関数、MMX 命令を使用するように最適化された関数、および機能を要求しない汎用の関数が含まれています。ベースとなるシステムには SSE2 と MMX が両方ともに備わっています。デフォルトでは、完全に最適化された SSE2 関数が使用されます。
LD_HWCAP 定義を使用することによって、SSE2 機能を削除して、MMX 命令用に最適化された関数を使用するように、libfoo.so および libbar.so を制限できます。LD_CAP_FILES を定義するもっとも柔軟な方法は、必要なファイルのベース名を使用することです。
$ LD_HWCAP=-sse2 LD_CAP_FILES=libfoo.so,libbar.so ./main
SSE2 および MMX の機能を削除して、汎用の関数だけを使用するように libfoo.so および libbar.so をさらに制限できます。
$ LD_HWCAP=-sse2,mmx LD_CAP_FILES=libfoo.so,libbar.so ./main
$ LD_DEBUG=basic LD_HWCAP=-sse2,mmx,cx8 ./main .... 02328: hardware capabilities (CA_SUNW_HW_1) - 0x5c6f \ [ SSE3 SSE2 SSE FXSR MMX CMOV SEP CX8 TSC FPU ] 02328: alternative hardware capabilities (CA_SUNW_HW_1) - 0x4c2b \ [ SSE3 SSE FXSR CMOV SEP TSC FPU ] ....