2017-11-05 32 views
1

私は光輸送の数値シミュレーションのために、Linux上で、C++ 11でパストレーサを書いていますし、私は最終的には、実行中に発生する可能性のある数値誤差をキャッチし、デバッグするためにいくつかの特定のC++ 11コードセグメントに対してのみ、SIGFPE生成を{activate | de-activate}することは可能ですか?

#include <fenv.h> 
... 
feenableexcept(FE_INVALID | 
       FE_DIVBYZERO | 
       FE_OVERFLOW | 
       FE_UNDERFLOW); 

を使用しています。

コードのある時点で、軸合わせ境界ボックス(AABB)に対する光線(線分)の交点を計算する必要があります。この計算では、私は非常に最適化された頑強なray-box intersection algorithmを使用しています。これは、IEEE 754標準に記述されているいくつかの特別な値(例えば、NaNとinf)の生成に依存しています。明らかに、私はこのレイボックス交差ルーチンによって特別に生成された浮動小数点例外をキャッチすることには興味がありません。

したがって、私の質問は以下のとおりです。

  1. それは(すなわち、レイ・ボックス交差点のコードセクションのための)コードの一部だけのセクションのための浮動小数点例外信号(SIGFPE)の生成を無効にすることは可能ですか?
  2. シミュレーションを計算するときには、 のパフォーマンスが非常に懸念されます。特定のコードセクションの例外 シグナルを抑制することができる場合は、 コンパイル時に実行できます(高価な関数呼び出しを避けることができるように、 世代中のコードの計装/除算)?

ありがとうございました!

+0

他のコードで浮動小数点トラッピングを有効にしますか?浮動小数点トラップは、デフォルトでは無効になっています。その場合、パストレースコードでは既にオフになっています。他のコードで浮動小数点トラッピングを特に必要としない限り、他のコードに対してはオンにする必要はありません。 –

+0

@EricPostpischil現在、私は浮動小数点のトラップをコード全体で有効にしています(質問にあるコードの抜粋を使用しています)。私がしたいのは、特定のコードセクションを除いて、コード全体に対して浮動小数点のトラップをオンにすることです。 –

答えて

1

標準C++では、コンパイル時に、浮動小数点のトラッピングを有効または無効にして実行する必要があるかどうかを指定する方法はありません。実際には、浮動小数点環境を操作するためのサポートは標準では要求されていないため、実装に実装があるかどうかは実装に依存します。標準のC++以外の答えは、使用している特定のハードウェアとソフトウェアによって異なりますが、その情報は報告されていません。

典型的なプロセッサでは、浮動小数点トラップを有効または無効にするには、プロセッサ制御レジスタを変更します。これを行うには関数呼び出しは必要ありませんが、あなたの質問で示唆するように、関数呼び出しは高価なものではありません。実際の命令は、プロセッサが命令の実行をシリアル化する必要があるため、時間を消費する可能性がある。 (現代のプロセッサは、何百もの命令を同時に実行することがあります - デコードされるもの、プロセッサ内のサブユニットを待つもの、計算のさまざまな段階にあるもの、結果を汎用レジスタに書き込むことなどがあります。制御レジスタの場合、プロセッサは現在実行中のすべての命令が終了するのを待たなければならず、次にレジスタを変更してから新しい命令の実行を開始する必要があります。)ハードウェアがこのように動作する場合、回避する方法はありません。 (一般的なこのようなハードウェアでは、制御レジスタを変更するために実行時命令を実際に実行せずにコードをコンパイルすることはできません)。

時間コストを軽減することができるかもしれませんパストレース計算をバッチ処理することで、グループ全体で2つの浮動小数点制御レジスタの変更(トラップをオフにする、1つオンにするには1つ)をグループ単位で実行します。

+0

"...浮動小数点のトラッピングはプロセッサ制御レジスタを変更することで実現できますか?これを行うには関数呼び出しは必要ありません..."私はトラップを有効/無効にするために "feenableexcept()"を使用していましたが...これはコントロールレジスタで直接行うことができますか? –

+0

@ChristianPagot:プロセッサには、制御レジスタをロードして格納するためのインテルの「LDMXCSR」や「STMXCSR」などの命令があります。一般的に、これらは直接アクセスしません。 feenableexceptルーチンがそれを行います。それらに直接アクセスする場合は、アセンブリコードの挿入やアセンブリ言語ソースファイルの使用にコンパイラの特別な機能(GCCの "asm"など)を使用する必要があります。また、コンパイラやオペレーティングシステムに関する特別な知識が必要です彼らがサポートする方法でこれを行うことができます(または少なくとも許容します)。それには一般的に意味がありません。 feenableexceptを呼び出すことができます。 –

+0

@ChristianPagot:結局のところ、feenableexceptへの実際の関数呼び出しが高価ではなく、関数呼び出しを実装する命令の実行時間が短いことがポイントです。高価なプロセッサ状態の変更であり、浮動小数点トラップ設定を変更したときにプロセッサの状態を変更することは避けられません。 –