1

最適化をオンにしてGCC for ARMを使用すると、本当に奇妙な問題が発生します。最適化を行わずに C++ アプリケーションをコンパイルすると、実行時に期待される結果を出力する実行可能ファイルが生成されます。最適化 (-O1) をオンにするとすぐに、アプリケーションが期待どおりの結果を生成できません。問題を特定するために数日間試しましたが、わかりません。初期化されていない変数をコードから削除し、厳密なエイリアシングが問題を引き起こす可能性がある箇所を修正しましたが、それでも適切な結果が得られませんでした。

私は ARM 用に GCC 4.2.0 を使用しており (プロセッサは ARM926ej-s です)、Montavista Linux ディストリビューションでアプリを実行しています。

以下は、私が使用しているフラグです。

-O1 -fno-unroll-loops fno-merge-constants -fno-omit-frame-pointer -fno-toplevel-reorder \
-fno-defer-pop -fno-function-cse -Wuninitialized -Wstrict-aliasing=3 -Wstrict-overflow=3 \
-fsigned-char -march=armv5te -mtune=arm926ej-s -ffast-math

-O1 フラグを取り除き、アプリケーションを再コンパイル/再リンクするとすぐに、適切な出力結果が得られます。フラグからわかるように、最適化を無効にしようとしましたが、問題が発生する可能性があると思いましたが、それでもうまくいきません。

この問題にさらに取り組む方法についての指針はありますか?

ありがとう

4

4 に答える 4

9

一般的に言って、「最適化は私のプログラムを壊す」と言うなら、あなたのプログラムが壊れているのは99.9%です。最適化を有効にすると、コードの障害のみが明らかになります。

また、最適化オプションについても簡単に説明する必要があります。非常に特殊な状況でのみ、標準オプション-O0、-O2、-O3、およびおそらく-Os以外のものが必要になります。それよりも具体的な設定が必要だと思われる場合は、最適化のマントラに注意してください

測定、最適化、測定。

ここでは決して「腸の感覚」で行かないでください。特定の非標準の最適化オプションがアプリケーションに大きなメリットをもたらすことを証明し、その理由を理解します(つまり、そのオプションが何をするのか、なぜそれがコードに影響を与えるのかを正確に理解します)。

これは目隠しをしてナビゲートするのに適した場所ではありません。

そして、最も防御的なオプション(-O1)をどのように使用するかを見て、次に5ダースの最適化を無効にし、次に-ffast-mathを追加すると、現在それを実行していると思います。

まあ、おそらく片目。

ただし、要点は次のとおりです。最適化を有効にするとコードが破損する場合は、コードに問題がある可能性があります。

編集:私はGCCマニュアルでこれを見つけました:

-ffast-math:このオプションは、数学関数のIEEEまたはISOルール/仕様の正確な実装に依存するプログラムの出力が正しくなくなる可能性があるため、-Oオプションでオンにしないでください。

これは、基本的に、あなた-O1 -ffast-mathが確かに正しいコードを壊す可能性があることを示しています。ただし、-ffast-math削除することで現在の問題が解消されたとしても、少なくともその理由を理解しておく必要があります。そうしないと、問題を後でもっと不便な瞬間(たとえば、製品がクライアントの場所で壊れたときなど)に問題と交換するだけになる可能性があります。それが本当に問題だったのでしょうか、それとも、によって明らかにされた数学コードを壊したのでしょうか?-ffast-math-ffast-math

于 2010-10-04T11:23:35.330 に答える
2

-ffast-math可能であれば避けるべきです。とりあえず使用-O1して、他のすべての最適化スイッチを削除してください。問題が解決しない場合は、デバッグを開始してください。

于 2010-10-04T11:08:59.417 に答える
1

コードを見ずに、「おそらくバグがある」よりも具体的にするのは難しいです。

最適化を有効にすると、プログラムのセマンティクスが変わる2つのシナリオがあります。

  • コンパイラにバグがある、または
  • コードにバグがあります。

後者がおそらく最も可能性が高いです。具体的には、プログラムのどこかで未定義動作に依存している可能性があります。これらのコンパイラフラグを使用してこのコンピュータでこのコンパイラを使用してコンパイルすると、たまたま真実であることに依存しますが、これは言語によって保証されていません。したがって、最適化を有効にした場合、GCCはその動作を維持する義務を負いません。

コードを見せてください。または、問題が発生するポイントに到達するまで、デバッガーでステップスルーします。

これ以上具体的にすることはできません。ダングリングポインタ、初期化されていない変数、エイリアシングルールの違反、または未定義の結果をもたらす多くのことの1つを実行している可能性があります(などi = i++

于 2010-10-04T11:20:19.313 に答える
1

最小限のテスト ケースを作成してみてください。プログラムを書き直して、エラーに影響しないものを削除します。その過程で自分でバグを発見する可能性が高いですが、そうでない場合は、投稿できる1 画面のサンプル プログラムを用意しておく必要があります。

ちなみに、他の人が推測しているように、それが問題の原因である場合-ffast-math(つまり、 でコンパイルしても問題なく-O1動作する場合) は、とにかく書き直す必要がある数学がそこにある可能性があります。少し単純化-ffast-mathしすぎていますが、浮動小数点数は正確ではないため、実際のハードウェアではわずかに異なる結果になる可能性がありますが、数学的な数を抽象化できるため、コンパイラーは基本的に計算を再配置できます。その種の浮動小数点の詳細に依存することは、意図的ではない可能性があります。

バグを理解したい場合は、最小限のテスト ケースが重要です。

于 2010-10-04T11:52:16.303 に答える