私は数日かけて理解しようとして本当に奇妙なエラーが発生したので、何が起こっているのかを理解するのに役立つコメントがないかどうかを確認したいと思います。
いくつかの背景。Boost1.45を使用してPython2.7.1にC++拡張機能を追加するソフトウェアプロジェクトに取り組んでいるため、すべてのコードはPythonインタープリターを介して実行されています。最近、回帰テストの1つを破ったコードに変更を加えました。この回帰テストは、おそらく数値の変動(たとえば、異なるマシン)に敏感すぎるため、修正する必要があります。ただし、この回帰は、元の回帰結果を生成したのと同じマシン/コンパイラで中断しているため、結果の違いをこの数値コードのスニペット(変更したコードとは明らかに無関係)まで追跡しました。
c[3] = 0.25 * (-3 * df[i-1] - 23 * df[i] - 13 * df[i+1] - df[i+2]
- 12 * f[i-1] - 12 * f[i] + 20 * f[i+1] + 4 * f[i+2]);
printf("%2li %23a : %23a %23a %23a %23a : %23a %23a %23a %23a\n",i,
c[3],
df[i-1],df[i],df[i+1],df[i+2],f[i-1],f[i],f[i+1],f[i+2]);
いくつかの数値表を作成します。ご了承ください:
- %a printsは、正確なASCII表現を提供します
- 左側(lhs)はc [3]であり、rhsは他の8つの値です。
- 以下の出力は、f、dfの境界から遠く離れたiの値に対するものです。
- このコードは、iのループ内に存在し、それ自体が複数のレイヤーをネストしています(したがって、これを再現するための分離されたケースを提供することはできません)。
そこで、ソースツリーのクローンを作成しました。コンパイルする2つの実行可能ファイルの唯一の違いは、このテストでは実行されない余分なコードがクローンに含まれていることです。唯一の違いはコードがメモリ内に存在する場所にあるはずなので、これはメモリの問題であるに違いないと思います...とにかく、2つの実行可能ファイルを実行すると、生成されるものの違いは次のとおりです。
diff new.out old.out
655,656c655,656
< 6 -0x1.7c2a5a75fc046p-10 : 0x0p+0 0x0p+0 0x0p+0 -0x1.75eee7aa9b8ddp-7 : 0x1.304ec13281eccp-4 0x1.304ec13281eccp-4 0x1.304ec13281eccp-4 0x1.1eaea08b55205p-4
< 7 -0x1.a18f0b3a3eb8p-10 : 0x0p+0 0x0p+0 -0x1.75eee7aa9b8ddp-7 -0x1.a4acc49fef001p-6 : 0x1.304ec13281eccp-4 0x1.304ec13281eccp-4 0x1.1eaea08b55205p-4 0x1.9f6a9bc4559cdp-5
---
> 6 -0x1.7c2a5a75fc006p-10 : 0x0p+0 0x0p+0 0x0p+0 -0x1.75eee7aa9b8ddp-7 : 0x1.304ec13281eccp-4 0x1.304ec13281eccp-4 0x1.304ec13281eccp-4 0x1.1eaea08b55205p-4
> 7 -0x1.a18f0b3a3ec5cp-10 : 0x0p+0 0x0p+0 -0x1.75eee7aa9b8ddp-7 -0x1.a4acc49fef001p-6 : 0x1.304ec13281eccp-4 0x1.304ec13281eccp-4 0x1.1eaea08b55205p-4 0x1.9f6a9bc4559cdp-5
<more output truncated>
c [3]の値は微妙に異なりますが、rhsの値はどれも違いがないことがわかります。つまり、どのように同一の入力が異なる出力を生み出しているのか。rhs式を単純化してみましたが、変更を加えると違いがなくなります。&c [3]を印刷すると、違いはなくなります。アクセスできる2つの異なるマシン(linux、osx)で実行している場合、違いはありません。これが私がすでに試したことです:
- valgrind(Pythonで多数の問題が報告されましたが、私のコードには何も報告されておらず、深刻に見えるものもありません)
- -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_ASSERT -D_GLIBCXX_DEBUG_PEDASSERT -D_GLIBCXX_DEBUG_VERIFY(ただし何もアサートされません)
- -fno-strict-aliasing(ただし、ブーストコードからエイリアシングコンパイル警告が表示されます)
問題のあるマシンでgcc4.1.2からgcc4.5.2に切り替えてみましたが、この特定の孤立した違いはなくなりました(ただし、リグレッションは失敗するため、別の問題であると想定します)。
問題をさらに切り分けるために私にできることはありますか?将来の参考のために、この種の問題をより迅速に分析または理解する方法はありますか?たとえば、rhsが変更されていないのにlhsが変更されているという私の説明を考えると、あなたは何を結論付けますか?
編集:問題は完全に原因でした-ffast-math
。