4

短いバージョン: DLL 内で CPU 固有の命令を利用することが可能かどうか、またどのように最適なのか疑問に思っていますか?

少し長いバージョン: Microsoft などから (32 ビット) DLL をダウンロードする場合、1 つのサイズですべてのプロセッサに適合するようです。

これは、それらが最小公分母 (つまり、OS でサポートされる最小プラットフォーム) 用に厳密に構築されていることを意味しますか? または、DLL 内の単一のインターフェイスをエクスポートするために使用されるテクニックがありますが、最適なパフォーマンスを得るために舞台裏で CPU 固有のコードを利用しますか? もしそうなら、それはどのように行われますか?

4

5 に答える 5

6

標準的な手法については知りませんが、そのようなことを行う必要がある場合は、DllMain() 関数にコードを記述して、CPU の種類を検出し、それぞれの CPU 最適化バージョンへの関数ポインターをジャンプ テーブルに入力します。関数。

CPU の種類が不明な場合の最小公倍数関数も必要です。

現在の CPU 情報は、次のレジストリで確認できます。

HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor
于 2008-09-25T02:42:49.843 に答える
2

DLL は、WIN32 が実行されるすべてのコンピューターで動作することが期待されているため、一般的に i386 命令セットに固執しています。特定の命令セットの機能/コードを公開する公式の方法はありません。手動で透過的に行う必要があります。

基本的に使用される手法は次のとおりです。 - 実行時に MMX、SSE などの CPU 機能を決定する - 存在する場合はそれらを使用し、存在しない場合はフォールバック コードを用意します。

コンパイラを i386 以外に最適化することはできないため、インライン アセンブラで特定の命令セットを使用してコードを記述する必要があります。このための高言語ツールキットがあるかどうかはわかりません。CPU の機能を判断するのは簡単ですが、アセンブラーで行う必要がある場合もあります。

于 2008-09-25T02:41:54.243 に答える
1

SSE/SSE2 最適化を取得する簡単な方法は/arch、MSVC の引数を使用することです。フォールバックについては心配しません。非常にニッチなアプリケーションでない限り、それ以下のものをサポートする理由はありません。

http://msdn.microsoft.com/en-us/library/7t5yh4fd.aspx

gcc/g++ には同等のフラグがあると思います。

于 2008-09-25T03:02:12.777 に答える
1

Intel の ICC は、異なるアーキテクチャ用にコードを 2 回コンパイルできます。そうすれば、ケーキを持って食べることができます。(OK、2 つのケーキが得られます。DLL は大きくなります)。また、MSVC2005 でさえ、非常に特殊なケースでそれを行うことができます (たとえば、memcpy() は SSE4 を使用できます)。

異なるバージョンを切り替える方法はたくさんあります。ロード プロセスには DLL からの関数が必要なため、DLL がロードされます。関数名はアドレスに変換されます。解決策の 1 つは、このルックアップを関数名だけでなく、プロセッサの機能にも依存させることです。別の方法では、名前からアドレスへの関数が中間ステップでポインターのテーブルを使用するという事実を使用します。テーブル全体を切り替えることができます。または、重要な機能内にブランチを作成することもできます。そのため、foo() は foo__sse4 を呼び出します。

于 2008-09-25T11:01:27.537 に答える
1

Microsoft からダウンロードした DLL は、一般的な x86 アーキテクチャを対象としています。これは、多数のマシンで動作する必要があるという単純な理由からです。

Visual Studio 6.0 のタイム フレームまで (変更されたかどうかはわかりません)、Microsoft は DLL を速度ではなくサイズで最適化していました。これは、DLL の全体的なサイズの縮小により、コンパイラが生成できる他のどの最適化よりもパフォーマンスが向上したためです。これは、マイクロ最適化による速度向上は、CPU がメモリを待機しないことによる速度向上に比べて明らかに低いためです。速度の真の向上は、I/O の削減または基本アルゴリズムの改善から得られます。

プログラムの中心で実行されるいくつかの重要なループだけが、呼び出される回数が非常に多いため、マイクロ最適化の恩恵を受けることができます。コードの約 5 ~ 10% のみがこのカテゴリに分類される可能性があります。このような重要なループは、Microsoft のソフトウェア エンジニアによってアセンブラーで既にある程度最適化されており、コンパイラーが検出できるほど多くは残されていないので安心できます。(期待しすぎなのはわかっていますが、彼らがこれを行うことを願っています)

ご覧のとおり、DLL コードの増加による欠点は、さまざまなアーキテクチャ用に調整された追加バージョンのコードを含むことだけです。このコードのほとんどはめったに使用されないか、CPU サイクルのほとんどを消費する重要なコードの一部ではありません。 .

于 2008-09-25T04:33:33.820 に答える