1

私はここの家々を回って、解決策を見つけたと思っていました。確かに、私が知っている問題を正しく特定しているように見えますが、すべてのシステム テスト ケースの約半分で原因不明のクラッシュが発生することもあります。

問題は、コードがクライアント コードを dll として呼び出す必要があることです。私たちはコードを制御できますが、クライアントのコードは制御できません。経験上、クライアントのコードが常に完璧であるとは限らないことがわかっています。プログラムを終了して何が問題なのかを明確に示すことで、セグメンテーション違反から保護しましたが、クライアントのコードから発生するゼロ除算の例外もいくつかありました。その後終了します。

私がやりたかったことは次のとおりです。

  1. クライアントの dll を実行する直前に、浮動小数点イントロスペクションをオンに切り替えます。
  2. クライアント コードを実行します。
  3. 問題がないか確認してください。
  4. 速度を上げるためにイントロスペクションをオフにします。

理論的にはこれを行う方法はいくつかありますが、多くは VS2010 では機能しないようです。

float_point プラグマを使用しようとしています:

#pragma float_control(except, on, push)

// run client code

#pragma float_control(pop)

__asm fwait;    // This forces the floating point unit to synchronise
if (_statusfp() & _SW_ZERODIVIDE)
{
    // abort the program
}

これは理論的には問題ないはずであり、実際には 50% の確率でうまく機能します。

問題は float_point コントロールがオンのままで、コードの他の場所で問題を引き起こす可能性があると考えています。

microsoft.com によると:

「/fp:precise、/fp:fast、/fp:strict、および /fp:except スイッチは、ファイルごとに浮動小数点セマンティクスを制御します。float_control プラグマは、関数ごとにそのような制御を提供します。 ."

ただし、コンパイル中に次の警告が表示されます。

警告 C4177: #pragma 'float_control' は、グローバル スコープまたは名前空間スコープでのみ使用する必要があります

一見、真っ向から矛盾している。

だから私の質問は:

  1. ドキュメントは正しいですか、それとも警告ですか (私は警告に賭けています)?
  2. これを行う信頼できる安全な方法はありますか?
  3. 私はこれを行う必要がありますか、それとも危険すぎますか?
4

1 に答える 1

2

あなたがしようとした

#pragma float_control(except, on, push)

// run client code

#pragma float_control(pop)

それはそれがどのように機能するかではありません。これはコンパイラ ディレクティブであり、つまり

#pragma float_control(except, on, push)

// This entire function is compiled with float_control exceptions on.
// Therefore, the pragma has to appear outside the function, at global scope.

#pragma float_control(pop)

そしてもちろん、この設定はコンパイルされている関数にのみ影響し、クライアントなどの関数が呼び出す可能性のある関数には影響しません。#pragma が既にコンパイルされたコードを変更できる方法はありません。

だから、答え:

  1. どちらも正しい
  2. はい、_controlfp_s
  3. SSE2 ステータスがないため、少なくとも不完全です
于 2013-12-12T14:29:45.650 に答える