私のCコードには次の式があります
k * dl * (1.0 + pHold / centre
+ (pHold * pHold) / (2.0 * centre * centre)
- square / (2.0 * centre))
浮動小数点除算は乗算よりもはるかにコストがかかることを知っており、しばらくこれと格闘してきました。これを並べ替えて分割を切り取る方法はありますか?
ありがとう
私のCコードには次の式があります
k * dl * (1.0 + pHold / centre
+ (pHold * pHold) / (2.0 * centre * centre)
- square / (2.0 * centre))
浮動小数点除算は乗算よりもはるかにコストがかかることを知っており、しばらくこれと格闘してきました。これを並べ替えて分割を切り取る方法はありますか?
ありがとう
ただし、方程式自体を最適化する必要があることが確実な場合は、 の乗法逆数がcentre
方程式に 4 回現れるという事実を使用して、分割数を 1 に減らすことができます。
double centreInv = 1.0 / centre;
double pHoldToCentre = pHold * centreInv;
double result =
k * dl * (1.0 + pHoldToCentre
+ 0.5 * pHoldToCentre * pHoldToCentre
- 0.5 * square * centreInv);
また、これらの種類の変更は実際にこの方程式の結果に影響を与える可能性があるため、変更する場合は、それでも目的の出力が得られることを確認してください。
分数の分母を見ると、共通の分数を作成すると、割り算を 1 回だけ実行できることがわかります (掛け算が増える代わりに)。
k * dl * (1.0
+ pHold / (centre)
- square / (2.0 * centre)
+ (pHold * pHold) / (2.0 * centre * centre)
)
浮動小数点乗算が浮動小数点除算より優れていることが確実な場合は、次のようにします。
k * dl * (1.0
+ (pHold * 2.0 * centre) / (2.0 * centre * centre)
- (square * centre) / (2.0 * centre * centre)
+ (pHold * pHold) / (2.0 * centre * centre)
)
これは次のようになります。
k * dl * (1.0
+ ( (pHold * 2.0 * centre)
- (square * centre)
+ (pHold * pHold) ) / (2.0 * centre * centre)
)
少なくとも 1 つを切り取ることができます。
k * dl * (1.0 + (pHold
+ (pHold * pHold) / (2.0 * centre)
- square * 0.5) / centre)
昔は、おそらくこう書いていたでしょう。
oocenter = 1/center;
そしてそれを式で使用しました
k * dl * (1.0 + pHold * oocentre
+ pHold * pHold * 0.5 * oocentre * oocentre
- square * 0.5 * oocentre)
最近では、コンパイラはそれを行うのに十分スマートであると私は信じています。ベクトル化と並列化に取り組むことをお勧めします。
こんにちは、私はプログラミングCのアイデアがありません:)
ただし、k、dl、pHold、center、square がすべて変数であるとすると、この数式は次のように簡略化できます。
k*dl*(2.0* centre * centre + 2.0 * centre * pHold - centre *square + pHold * pHold)
/ (2.0 * centre * centre)
変数を 1 文字の変数に置き換え、http://www.wolframalpha.comを使用します
編集: Nikos C は基本的に同じ答えを持っていますが、2c を因数分解しています。どちらのパフォーマンスが優れているかをテスト/選択できます。
これを全体で 1 つの部門だけに減らすことができます。
k * dl * (2 * centre * (centre + pHold) + pHold * pHold - centre * square)
/ (2.0 * centre * centre)