5

コンパイラーがコードの最適化と実行速度の向上にますます優れていることはわかっていますが、私の質問は、浮動小数点演算を最適化して精度を高めることができるコンパイラーです。

たとえば、基本的なルールは、加算の前に乗算を実行することです。これは、浮動小数点数を使用した乗算と除算では、加算と減算ほどの不正確さは発生しませんが、加算と減算によって発生する不正確さの大きさが増加する可能性があるためです。多くの場合、最初に実行します。

したがって、次のような浮動小数点演算

y = x*(a + b); // faster but less accurate

に変更する必要があります

y = x*a + x*b; // slower but more accurate

上で示したように、速度を犠牲にして浮動小数点の精度を向上させるために最適化するコンパイラはありますか?それとも、浮動小数点演算の精度を見ずにコンパイラの速度を上げることの主な関心事ですか?

ありがとう

更新:選択された回答は、このタイプの最適化が機能しない非常に良い例を示しているため、コンパイラーはyを評価するためのより正確な方法を事前に知ることはできません。反例をありがとう。

4

3 に答える 3

10

あなたの前提は間違っています。 x*(a + b)、は(一般的に)。と同じくらい正確ですx*a + x*b。実際、2つの浮動小数点演算のみを実行する(したがって、2つの丸め誤差のみが発生する)のに対し、後者は3つの演算を実行するため、多くの場合、より正確になります。

x、、aおよびアプリオリの値の予想される分布について何か知っている場合はb、十分な情報に基づいて決定を下すことができますが、コンパイラーはそのタイプの情報にアクセスすることはほとんどありません。

それはさておき、プログラムを書いている人が実際にその特定の一連の操作によって引き起こされる正確な丸めを意味し x*(a+b)、具体的に望んでいた場合はどうなりますか?この種のことは、実際には高品質の数値アルゴリズムではかなり一般的です。

プログラマーが意図したと思うことではなく、プログラマーが書いたことを実行する方がよいでしょう。

編集-あなたが提案した変換が精度の壊滅的な損失をもたらす場合を説明するための例:仮定

x = 3.1415926535897931
a = 1.0e15
b = -(1.0e15 - 1.0)

次に、で評価すると、次のdoubleようになります。

x*(a + b) = 3.1415926535897931

しかし

x*a + x*b = 3.0
于 2010-01-14T00:08:47.700 に答える
2

コンパイラは通常、速度よりも精度を「最適化」します。精度は、IEEE754標準の正確な実装として定義されます。整数演算はオーバーフローを引き起こさない方法で並べ替えることができますが、FP演算はプログラマーが指定したとおりに実行する必要があります。これは数値の精度を犠牲にするかもしれませんが(通常のCコンパイラはそれを最適化するために装備されていません)、プログラマーが求めたものを忠実に実装します。

精度を手動で最適化していないと確信しているプログラマーは、GCCのようなコンパイラー機能を有効に-funsafe-math-optimizations-ffinite-math-only、場合によっては余分な速度を引き出すことができます。しかし、通常はあまり利益はありません。

于 2010-01-14T06:00:58.720 に答える
0

いいえ、ありません。スティーブン・キャノンは、これが愚かな考えである理由をいくつか挙げています。彼は正しいです。したがって、これを行うコンパイラは見つかりません。

プログラマーが操作している数値の範囲についてある程度の知識を持っている場合は、括弧、一時変数、および同様の構成を使用して、コンパイラーにどのように処理したいかを強く示唆することができます。

于 2010-01-14T00:21:29.270 に答える