23

fp:strictモードのMSVCを使用して、Cライブラリの超越的な数学関数のアセンブリに足を踏み入れました。それらはすべて同じパターンに従っているようです。これがで何が起こるかですsin

まず、「disp_pentium4.inc」というファイルからのディスパッチルーチンがあります。___use_sse2_mathfcns変数が設定されているかどうかをチェックします。の場合はを呼び出し__sin_pentium4、そうでない場合はを呼び出します__sin_default

__sin_pentium4("sin_pentium4.asm"内)は、引数をx87 fpuからxmm0レジスタに転送することから始め、SSE2命令を使用して計算を実行し、結果をfpuにロードします。

__sin_default(「sin.asm」内)は、変数をx87スタックに保持し、単に。を呼び出しますfsin

したがって、どちらの場合も、オペランドはx87スタックにプッシュされて返され、呼び出し元に対して透過的になりますが、___use_sse2_mathfcns定義されている場合、操作は実際にはx87ではなくSSE2で実行されます。

x87超越関数は、実装によって動作がわずかに異なることで有名ですが、SSE2コードの特定の部分は常に再現可能な結果を​​もたらすはずなので、この動作は私にとって非常に興味深いものです。

コンパイル時または実行時に、SSE2コードパスが使用されることを確実に判断する方法はありますか?私はアセンブリを書くのが上手ではないので、これにアセンブリの記述が含まれる場合は、コード例をいただければ幸いです。

4

3 に答える 3

11

math.hを注意深く調べて答えを見つけました。これは、と呼ばれるメソッドによって制御され_set_SSE2_enableます。これはここに記載されている公開シンボルです:

CRT数学ルーチンでのStreamingSIMDExtensions 2(SSE2)命令の使用を有効または無効にします。(SSE2はデフォルトで有効になっているため、この機能はx64アーキテクチャでは使用できません。)

これにより、前述の___use_sse2_mathfcnsフラグが指定された値に設定され、_pentium4SSE2ルーチンの使用が効果的に有効または無効になります。

ドキュメントには、これは特定の超越関数にのみ影響することが記載されていますが、分解を見ると、これはそれらすべてに影響を与えるようです。

編集:すべての関数にステップインすると、以下を除いてすべてSSE2で使用可能であることがわかります。

  • fmod
  • シン
  • コッシュ
  • タン
  • 平方根

Sqrtは最大の違反者ですが、組み込み関数を使用してSSE2に実装するのは簡単です。他の人にとっては、おそらくサードパーティのライブラリを使用する以外に簡単な解決策はありませんが、私はおそらくそれなしで行うことができます。

于 2013-03-09T20:46:44.103 に答える
4

Cランタイムの代わりに独自のライブラリを使用してみませんか?これにより、コンピューター間の一貫性がさらに強力に保証されます(おそらく、CランタイムはDLLとして提供され、時間の経過とともにわずかに変化する可能性があります)。

CRlibmをお勧めします。すでにSSE2をターゲットにしていて、FPUの丸めモードを変更するつもりがない限り、それを使用するのに理想的な状態にあり、より正確な実装を見つけることはできません。

于 2013-03-09T18:52:33.783 に答える
2

簡単な答えは、ライブラリの実装固有の詳細も含まない限り、ライブラリが何をするかをコードで確実に伝えることはできないということです。これらはコードを完全に移植不可能にします-同じコンパイラの2つの異なるビルドでさえ、ライブラリの内部を変更する可能性があります。

もちろん、移植性が問題ではない場合は、extern <type> ___use_sse2_mathfcns;それが本当かどうかを使用して確認することは明らかに機能します。

プロセッサにSSE2が搭載されていて、十分に最新のライブラリを使用している場合は、可能な限りSSE2を使用することを期待しています。しかし、確かにそれを言うことは別の問題です。

これがコードにとって重要な場合は、独自の超越関数を実装してそれらを使用します。これが同じ結果を保証する唯一の方法です。または、適切なインラインアセンブラ(または超越)コードを使用して、選択sinした、などの値を計算し、それらをライブラリが提供するおよび関数cosと比較します。sin()cos()

于 2013-03-09T18:48:00.090 に答える