我的 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);
另请注意,这些更改实际上可能会影响此方程式的结果,因此如果您决定更改它,请确保它仍能产生所需的输出。
如果您查看分数的分母,您会发现制作一个共同的面额将允许您只进行一次除法(以更多的乘法为代价):
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)
)
在代数上,您可以将其简化为一个除法。使用:
k
为了k
d
为了dl
p
为了pHold
c
为了centre
s
为了square
你的等式是:
p p.p s
k.d ( 1 + --- + ----- - --- )
c 2.c.c 2.c
转换为:
k.d ( 2.c.c + 2.c.p + p.p - c.s )
---------------------------------
2.c.c
并因此
k.d (2.c (c + p) - c.s + p.p)
-----------------------------
2.c.c
或者,就您的原始变量而言:
(k * dl * (2 * centre * (centre + pHold) - centre * square + pHold * pHold)) /
(2 * centre * 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)
将变量替换为单个字符变量并使用http://www.wolframalpha.com
编辑:Nikos C 的答案基本相同,但要考虑 2c。您可以测试/选择哪一个表现更好。
您可以将其减少到总体上只有一个部门:
k * dl * (2 * centre * (centre + pHold) + pHold * pHold - centre * square)
/ (2.0 * centre * centre)
你至少删掉了一个:
k * dl * (1.0 + (pHold
+ (pHold * pHold) / (2.0 * centre)
- square * 0.5) / centre)