4

VS2013からVS2015への移行中に発生した問題の小さな例があります。 VS2015では、さらにコード例で浮動小数点無効な操作が発生します。VS2015とVS2013の最適化が異なると浮動小数点例外が発生する

enter image description here

int main() 
{ 
    unsigned int enableBits = _EM_OVERFLOW | _EM_ZERODIVIDE | _EM_INVALID; 

    _clearfp(); 
    _controlfp_s(0, ~enableBits, enableBits); 

    int count = 100; 
    float array[100]; 

    for (int i = 0; i < count; ++i) 
    { 
     array[i] = (float)pow((float)(count - 1 - i)/count, 4); //this causes exception in VS2015 
    } 

    return 0; 
} 

そのおそらく異なる最適化によって引き起こされるので、これが唯一のリリースモードで起こります。このコードに何か問題がありますか?これはVS 2015のバグですか?

(働く私は例えば代わり​​の異なる変数を使用する)ので、私はいくつかの体系的な修正ではない回避策を探しています全体のコードベース全体でこのような問題を発見するために、そのハード私はまた、生成された確認VS2013のように見えますが、128bitレジストリ全体を使用して1つの部門で4つの浮動小数点演算を実行します。 VS2015では、2つの浮動小数点演算しか行わないようで、レジストリの残りはゼロ(またはいくらかのガベージ)で、おそらくこの例外を導入します。

例外を引き起こす命令が画像に記録されています。

VS2013 VS2013

とVS2015 enter image description here

すべてのヘルプは理解されるであろう。おかげさまで

+0

Hmm。完全な最適化を有効にして、自分のコードが私のために働きます(リリース/ x64)。あなたのVSは最新ですか? 「特別な」コンパイラ設定はありますか? –

+0

VS2015アップデート3を使用しました。リリース+最適化(Maximize Speed/O2)と組み込み関数(Yes/Oi)の標準設定を使用しました。 – Bezousek

答えて

1

これは浮動小数点例外を使用するだけでなく、浮動小数点の最適化を可能にする相互作用のようです。

コードでは、一度に2回の繰り返し(ループアンローリング)を行いますが、XMMレジスタの4つの浮動小数点から4回に分割するdivpsを使用しています。 XMMレジスタの上位2つの浮動小数点数は使用されず、ゼロです。これらのスロットの値の除算の結果は使用されないため、通常は問題になりません。しかし、カスタム例外処理を設定すると、使用されない値を生成していても表示される無効なop例外が発生します。

あなたの選択は、/ fp:strictを設定して最適化を無効にするので、この作業を行います(しかし、明らかにコードを遅くする)か、controlfp呼び出しを削除します。

+0

コメントありがとうございます。この設定は厳格に役立ちますが、どこに設定するべきか分かりません。私は一般的に数百のファイルを計算していて、どこでも減らそうとはしません。 VS2015とVS2013の違いは/ fp:preciseでもうまくいきます。 – Bezousek

関連する問題