1

私のCコードには次の式があります

k * dl * (1.0 + pHold / centre
       + (pHold * pHold) / (2.0 * centre * centre)
       - square / (2.0 * centre))

浮動小数点除算は乗算よりもはるかにコストがかかることを知っており、しばらくこれと格闘してきました。これを並べ替えて分割を切り取る方法はありますか?

ありがとう

4

7 に答える 7

7
一部の部分 を実際に最適化する前に、次のことを行う必要があることに注意してください。
  • それが正しいことを確認してください
  • より高いレベルでこれを最適化する方法がないことを確認してください
    ~私のプログラムはこの計算を実際に必要な回数以上呼び出していませんか?
    以前の結果を使用してもよろしいですか?(動的計画法とは? )
  • ボトルネックがどこにあるかがわかったら、ベンチマークを実行する必要があります:
    ~遅いようです... どれくらい「遅い」のでしょうか? ...どのくらい「速く」なる必要がありますか?

ただし、方程式自体を最適化する必要があることが確実な場合は、 の乗法逆数が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);

また、これらの種類の変更は実際にこの方程式の結果に影響を与える可能性があるため、変更する場合は、それでも目的の出力が得られることを確認してください。

于 2013-10-13T22:16:56.803 に答える
4

分数の分母を見ると、共通の分数を作成すると、割り算を 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)
)
于 2013-10-13T22:23:22.300 に答える
0

少なくとも 1 つを切り取ることができます。

k * dl * (1.0 + (pHold
       + (pHold * pHold) / (2.0 * centre)
       - square * 0.5) / centre)
于 2013-10-13T22:17:33.150 に答える
0

昔は、おそらくこう書いていたでしょう。

oocenter = 1/center; 

そしてそれを式で使用しました

k * dl * (1.0 + pHold * oocentre
       + pHold * pHold * 0.5 * oocentre * oocentre
       - square * 0.5 * oocentre)

最近では、コンパイラはそれを行うのに十分スマートであると私は信じています。ベクトル化と並列化に取り組むことをお勧めします。

于 2013-10-13T22:20:05.300 に答える
0

こんにちは、私はプログラミング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 を因数分解しています。どちらのパフォーマンスが優れているかをテスト/選択できます。

于 2013-10-13T22:21:32.583 に答える
0

これを全体で 1 つの部門だけに減らすことができます。

k * dl * (2 * centre * (centre + pHold) + pHold * pHold - centre * square)
/ (2.0 * centre * centre)
于 2013-10-13T22:21:48.960 に答える