2013-10-27 22 views
13

C/C++で特定のアルゴリズムを実装することによって解決する必要がある科学計算の問題の大部分は、倍精度よりはるかに低い精度が要求されます。たとえば、1e-6,1e-7の精度は、ODEソルバーまたは数値積分の場合の99%の精度をカバーします。私たちがより高い精度を必要とするまれなケースでも、通常、倍精度に近い精度に達することを夢見る前に数値的方法自体が失敗します。例:単純なRunge-Kutta法から1e-16の精度を期待することはできません。この場合、倍精度の要件は、間違った答えのより良い近似を求めることと似ています。浮動小数点の最適化 - ガイドライン

次に、積極的な浮動小数点の最適化は、コードをより高速に(非常に速く!)し、特定の問題のターゲット精度に影響を与えないため、ほとんどの場合Win-Winのようです。つまり、特定の実装/コードがfpの最適化に対して安定していることを確認することは非常に難しいようです。古典的な(やや邪魔になる)例:GNU科学ライブラリであるGSLは、市場の標準的な数値ライブラリだけでなく、非常によく書かれた図書館でもあります(より良い仕事をしているとは思いません)。しかし、GSLはfpの最適化に対して安定していません。例えば、intelコンパイラを使ってGSLをコンパイルすると、フラグをオンにしてfpの最適化を無効にしない限り、内部テストは失敗します。

私の質問は、積極的な浮動小数点最適化に対して安定したコードを記述するための一般的なガイドラインがあるかどうかです。これらのガイドラインは言語(コンパイラ)固有のものですか?もしそうなら、C/C++(gcc/icc)ベストプラクティスは何ですか?

注1:この質問では、gcc/iccのfp最適化フラグについては問いません。

注2:この質問では、C/C++最適化(ロットと呼ばれる小さな関数に仮想関数を使用しないなど)の一般的なガイドラインについては問いません。

注3:この質問は、ほとんどの標準fp最適化(x/x - > 1など)のリストを要求していません。

注4:これは、古典的な「最もクールなサーバー名」に似ている主観的/非主観的な質問ではないと強く信じています。あなたが同意しない場合(私が具体的な例/コード/問題を提供していないため)、コミュニティのwikiとしてフラグを立ててください。私はいくつかのステータスポイントを得ることよりも、答えにもっと興味があります(重要ではない - あなたがポイントを得る!)。

+2

エラーが蓄積されます。すべての計算が倍精度で行われても、最終結果は最後のビットまでは正確ではありません。どこでもfloatを使用している場合は、適切なエラー解析を行い、回答のビット数が信頼できるものであればそれを調べる必要があります。もちろん、同じことを二重に行うべきです。 –

+2

一般的な数値の安定性は、慎重に選ばれた、ほとんど脆弱な中間ステップを介して行われることが多く、特に有限精度浮動小数点演算の非結合文字を克服するように設計されています。積極的な最適化は、例えば、実行順序を変更して反復調整が助けになるかもしれませんが、答えを得るのに時間がかかります。プロのヒント:質問を[Computational Science](http://scicomp.stackexchange.com/)のサイトに掲載したいかもしれません。 –

答えて

12

コンパイラメーカはnumerically stable algorithms以上の影響が最小限であるという主張で-ffast-math種類の最適化を正当化します。

したがって、これらの最適化に対して堅牢なコードを作成する場合は、数値的に安定したコードのみを書き込むことが十分条件です。

あなたの質問は、「数値的に安定したコードを書くにはどうすればいいですか?これはあなたの質問が少し広範であるかもしれないところです:主題に特化した全書があります。すでに私がリンクしているWikipediaのページには良い例があり、hereも良い例です。私は特に本を推薦できませんでしたが、これは私の専門分野ではありません。

注1:数値安定性の望ましい点は、コンパイラの最適化を超えています。選択肢がある場合は、-ffast-mathスタイルの最適化を計画していなくても、数値的に安定したコードを書いてください。厳密なIEEE 754浮動小数点セマンティクスでコンパイルした場合でも、数値的に不安定なコードは誤った結果をもたらす可能性があります。

注2:-ffast-math-styleフラグを指定してコンパイルすると、外部ライブラリが動作することは期待できません。浮動小数点の専門家によって書かれたこれらのライブラリは、IEEE 754計算の特性を持つ微妙なトリックを演奏する必要があるかもしれません。この種のトリックは、-ffast-mathの最適化によって壊れているかもしれませんが、コンパイラが期待する以上に性能を向上させます。浮動小数点計算では、ドメイン知識を持つエキスパートが毎回コンパイラを打ち負かします。たとえば、CRlibmにあるトリプルダブルの実装が多くあります。厳密なIEEE 754セマンティクスでコンパイルされていない場合、このコードは壊れます。コンパイラの最適化が中断する、より基本的なアルゴリズムは、Kahan summationです。安全でない最適化でコンパイルすると、c = (t - sum) - yc = 0に最適化されます。もちろん、これはアルゴリズムの目的を完全に破っています。

+1

ライブラリが "-ffast-math"で動作することは不可能ではありません。 GSL開発者のマイルストーン目標の1つは、GSLを安定性の低い状態で安定させることです(GSLのメールリストに関する報告書によると)。彼らは難しいと言いますが(不可能ではありません)。さらに、GSLは非常に信頼性が高く安定したアルゴリズムしか実装していません。ですから、これを解決することは不可能ではないコード問題です。>これを達成するにはC/C++に一般的なテクニックが必要です。 –

+2

@ViniciusMiranda私は "あなたは外部ライブラリを期待できない"と言った。すべての浮動小数点ライブラリに関する一般的な記述です。あなたが望むなら、浮動小数点ライブラリFをForallにすると、Fが '-ffast-math'で動作すると期待できます。 GSLの作者がこれらのオプションとの互換性を目指すなら、それらのオプションには適しています。私が言及した理由のために、誰もがそうではなく、場合によっては、意味をなさない。 –

関連する問題